Skip to content
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

Merged
merged 46 commits into from
Mar 6, 2020

Conversation

alrz
Copy link
Contributor

@alrz alrz commented Nov 3, 2019

Relates to #28489 (test plan for "target-typed new")

@jinujoseph jinujoseph added Area-Infrastructure Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee. and removed Area-Infrastructure labels Nov 5, 2019
@jcouv
Copy link
Member

jcouv commented Dec 11, 2019

@alrz Thanks for refreshing the target-typed new branch. Let me know when this is ready for a look. #Resolved

@alrz
Copy link
Contributor Author

alrz commented Dec 13, 2019

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 TestTupleEquality01). Other than that I guess I'd like to get feedback on possibly new conventions that we need to follow. Thanks. #Closed

@jcouv
Copy link
Member

jcouv commented Dec 13, 2019

Ok :-)
I'll take a look early next week. Thanks! #Resolved

@jcouv
Copy link
Member

jcouv commented Dec 17, 2019

Looking at this draft PR now.
This PR should probably not target master. Maybe we should review as-is, then we'll retarget to the feature branch once sign-offs are completed? #Resolved


internal partial class UnboundObjectCreationExpression
{
public override object Display => "new()";
Copy link
Member

@jcouv jcouv Dec 17, 2019

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

Copy link
Contributor Author

@alrz alrz Dec 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have three options:

  1. always new() (current iteration)
  2. always new(...) (previous iteration)
  3. conditionally new() if there's no args, otherwise new(...)

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

Copy link
Member

@jcouv jcouv Jan 21, 2020

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

Copy link
Member

@333fred 333fred Feb 4, 2020

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

Copy link
Member

@333fred 333fred Feb 12, 2020

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

// 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();`.
Copy link
Member

@jcouv jcouv Dec 17, 2019

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();
Copy link
Member

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?)

@alrz
Copy link
Contributor Author

alrz commented Feb 20, 2020

We should add a flag to IObjectCreationOperation, and conditionally include it in the writer when true.

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);
Copy link
Member

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.

Copy link
Member

@333fred 333fred left a 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.

alrz and others added 3 commits February 26, 2020 10:11
# Conflicts:
#	src/Compilers/CSharp/Portable/Errors/MessageID.cs
#	src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
@alrz
Copy link
Contributor Author

alrz commented Feb 26, 2020

@jcouv @333fred I think I've addressed all the comments.

@jcouv
Copy link
Member

jcouv commented Feb 26, 2020

Yay!
Steps forward:

  1. I'll reset the features/target-typed-new branch to match master
  2. retarget this PR to the feature branch
  3. merge this PR

After that, we can discuss and address the remaining test plan items (semantic model, IOperation, IDE stuff, manual validation)

@jcouv jcouv changed the base branch from master to features/target-typed-new February 26, 2020 23:44
@jcouv
Copy link
Member

jcouv commented Feb 26, 2020

Steps 1 and 2 are done.
Will squash the PR when CI is green.

@@ -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.
Copy link
Member

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

Copy link
Contributor Author

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,
Copy link
Member

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?

Copy link
Contributor Author

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
Copy link
Member

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.

Copy link
Contributor Author

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)
Copy link
Contributor Author

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

@alrz
Copy link
Contributor Author

alrz commented Feb 27, 2020

I think it's worth considering interaction with new[] while we reconfirm with LDM
We may want to change conversion rules based on that. See dotnet/csharplang#2701 (comment)

@jcouv jcouv merged commit a501031 into dotnet:features/target-typed-new Mar 6, 2020
@jcouv
Copy link
Member

jcouv commented Mar 6, 2020

Merged!
Thanks @alrz for all the work and dedication. It's a pretty cool feature :-)

Next steps:

  • I think there were a few more test scenarios suggested above (speculative semantic model and maybe some other things), could you handle those? (@333fred could you recap what you had identified?)
  • I'll raise in LDM again as final greenlight before merging to master
  • I'll do an IDE test pass on the feature and implement FAR.
  • We should refresh the speclet and make it more spec-like (ie. identify the areas of the specification that need updating)

@alrz
Copy link
Contributor Author

alrz commented Mar 7, 2020

I think there were a few more test scenarios suggested above (speculative semantic model and maybe some other things)

For TypeInfo, we never attempt to convert a typeless expression to get a type. The result is as good as default literals: no type.

We should refresh the speclet

There's dotnet/csharplang#1989 though it's out of sync.
I think we should also mention object equality (probably should be an error)

@alrz alrz deleted the target-typed-new branch March 8, 2020 13:56
@333fred
Copy link
Member

333fred commented Mar 9, 2020

My list is:

  • IOperation changes. These don't require an explicit api design meeting ahead of time, they're very small. We'll take the change and do it as part of the general API review session for whatever VS release this ships in preview with.
  • SpeculativeModel changes. We don't need to try and infer anything for GetSpeculativeTypeInfo, but when we provide an entire statement (TryGetSpeculativeSemanticModel) that should end up inferring type info.

@333fred 333fred added the New Language Feature - Target-Typed New `new (args)` gets the created type inferred from context label Mar 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Community The pull request was submitted by a contributor who is not a Microsoft employee. New Language Feature - Target-Typed New `new (args)` gets the created type inferred from context
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants