-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rebase target-typed-new branch on top of master #39658
Rebase target-typed-new branch on top of master #39658
Conversation
@alrz Thanks for refreshing the target-typed new branch. Let me know when this is ready for a look. #Resolved |
The PR is almost ready - most of the things just work due to recent changes for handling target-typed expressions, Tuple equality still lacks in some scenarios (see |
Ok :-) |
Looking at this draft PR now. |
src/Compilers/CSharp/Test/Syntax/Parsing/TargetTypedObjectCreationParsingTests.cs
Outdated
Show resolved
Hide resolved
|
||
internal partial class UnboundObjectCreationExpression | ||
{ | ||
public override object Display => "new()"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"new()"; [](start = 42, length = 8)
nit: should we display the arguments too? or maybe put an ellipsis new(...)
Update: I see this is used for displaying diagnostics #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have three options:
- always
new()
(current iteration) - always
new(...)
(previous iteration) - conditionally
new()
if there's no args, otherwisenew(...)
I didn't like (2) because I suspect we'll have new()
most of the time. I'm fine with other two, I went with (1) for now to keep things simple.
#Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine to leave as-is (option 1). Thanks #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is used in error output, I don't think that this is fine. We should do option 3, and correctly display the arguments. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alrz I didn't see any response to this? #Closed
src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs
Outdated
Show resolved
Hide resolved
// We manually create an ImplicitNullable conversion | ||
// if the destination is nullable, in which case we | ||
// target the underlying type e.g. `S? x = new();` | ||
// is actually identical to `S? x = new S();`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is actually identical to
S? x = new S();
. [](start = 19, length = 43)
📝 let's remember to capture that in speclet #Closed
@@ -649,8 +649,8 @@ private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, Di | |||
{ | |||
resultSignature = signature; | |||
HashSet<DiagnosticInfo> useSiteDiagnostics = null; | |||
bool leftDefault = left.IsLiteralDefault(); | |||
bool rightDefault = right.IsLiteralDefault(); | |||
bool leftDefault = left.IsLiteralDefaultOrTypelessNew(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left.IsLiteralDefaultOrTypelessNew(); [](start = 39, length = 37)
📝 let's make sure that the speclet captures the rules around new()
and comparisons (when is object equality valid?)
# Conflicts: # src/Compilers/CSharp/Portable/CSharpResources.Designer.cs # src/Compilers/CSharp/Portable/CSharpResources.resx
I did not go though IOperation changes because it would need public API review and doesn't help much to be added in this PR. I see it's already tracked in the test plan (#28489) edit: also added a reminder for speculative semantic model |
{ } | ||
|
||
public BoundObjectCreationExpression Update(MethodSymbol constructor, ImmutableArray<BoundExpression> arguments, ImmutableArray<string> argumentNamesOpt, ImmutableArray<RefKind> argumentRefKindsOpt, bool expanded, | ||
ImmutableArray<int> argsToParamsOpt, ConstantValue constantValueOpt, BoundObjectInitializerExpressionBase initializerExpressionOpt, Binder binderOpt, TypeSymbol type) | ||
{ | ||
return this.Update(constructor, ImmutableArray<MethodSymbol>.Empty, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, constantValueOpt, initializerExpressionOpt, binderOpt, type); | ||
return this.Update(constructor, ImmutableArray<MethodSymbol>.Empty, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, constantValueOpt, initializerExpressionOpt, wasTargetTyped: false, binderOpt, type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wasTargetTyped: false, [](start = 201, length = 22)
These should be using the current state of wasTargetTyped
, not setting an explicit false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (commit 41), with one more suggestion above.
# Conflicts: # src/Compilers/CSharp/Portable/Errors/MessageID.cs # src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
6663353
to
b9e2751
Compare
Yay!
After that, we can discuss and address the remaining test plan items (semantic model, IOperation, IDE stuff, manual validation) |
Steps 1 and 2 are done. |
@@ -1542,6 +1542,19 @@ | |||
<Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> | |||
</Node> | |||
|
|||
<!-- | |||
This node is used to represent a target-typed object creation expression | |||
It does not survive past initial binding. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This only survives past initial binding in error cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually it doesn't (due to BindToNaturalType usages), unless we visit unconverted nodes (like in NullableWalker)
@@ -5890,6 +5890,7 @@ private enum ParseTypeMode | |||
AfterIs, | |||
DefinitePattern, | |||
AfterOut, | |||
AfterRef, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why we're seeing this change in the diff. I would expect this diff (at least in github UI) to only show the target-typed-new changes, but nothing from other merges.
Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is added in this PR, to avoid cascading diagnostics e.g. for new ref
@@ -8,6 +8,12 @@ | |||
*REMOVED*static Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(string text, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions options = null, string path = "", System.Text.Encoding encoding = null, System.Collections.Immutable.ImmutableDictionary<string, Microsoft.CodeAnalysis.ReportDiagnostic> diagnosticOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree | |||
*REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(Microsoft.CodeAnalysis.Text.SourceText text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Collections.Immutable.ImmutableDictionary<string, Microsoft.CodeAnalysis.ReportDiagnostic> diagnosticOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree | |||
*REMOVED*static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(string text, Microsoft.CodeAnalysis.ParseOptions options = null, string path = "", System.Text.Encoding encoding = null, System.Collections.Immutable.ImmutableDictionary<string, Microsoft.CodeAnalysis.ReportDiagnostic> diagnosticOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SyntaxTree | |||
*REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would only expect added APIs, but no removed APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has turned to an override now.
else | ||
|
||
var name = this.CreateMissingIdentifierName(); | ||
if (mode != ParseTypeMode.NewExpression) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where we want to distinguish between NewExpression and AfterRef
I think it's worth considering interaction with |
Merged! Next steps:
|
For TypeInfo, we never attempt to convert a typeless expression to get a type. The result is as good as
There's dotnet/csharplang#1989 though it's out of sync. |
My list is:
|
Relates to #28489 (test plan for "target-typed new")