-
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
Collection expressions: require applicable constructor and Add method for target type implementing IEnumerable #71592
Conversation
… for target type implementing IEnumerable
Is it expected that an Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:6417 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
We should consider reporting a specific error for collection expressions: "no applicable Add method that can be called with argument of type 'T'". #Resolved Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:5802 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
@@ -183,6 +182,19 @@ protected override Conversion GetInterpolatedStringConversion(BoundExpression so | |||
|
|||
Debug.Assert(elementType is { }); | |||
|
|||
if (collectionTypeKind == CollectionExpressionTypeKind.ImplementsIEnumerable) |
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.
Need to update breaking change document with the additional conversion requirements: an accessible .ctor callable with no arguments, and an accessible Add method callable with an argument of the iteration type.
For instance, Dictionary<string, object> d = [];
is no longer supported, and collection expressions cannot be converted to string
. #Resolved
Removed test since the diagnostics have changed ( Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:3756 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = True) |
{ | ||
if (!HasCollectionExpressionApplicableConstructor(node.Syntax, targetType, diagnostics)) | ||
{ | ||
reportedErrors = true; |
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.
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.
If so, consider adding a comment pointing to the code doing that
|
||
if (!HasCollectionExpressionApplicableAddMethod(node.Syntax, targetType, elementType, diagnostics)) | ||
{ | ||
reportedErrors = true; |
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.
It looks like we end up here for ListInterfaces_01
unit-test and report errors that HasCollectionExpressionApplicableAddMethod
reports. I think that the errors look confusing. Consider dropping the diagnostics and reporting a dedicated error instead. Something like "conversion from collection expression to type '{targetType}' doesn't exist because there is no accessible method that accepts value of type'{elementType}'" #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.
Dependencies can be dropped too, since we are reporting an error. Accurate tracking of dependencies is not supported for error scenarios
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.
Perhaps we can report "error CS1061: '{targetType}' does not contain a definition for 'Add' and no accessible extension method 'Add' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)" when HasCollectionExpressionApplicableAddMethod
doesn't report that itself.
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.
It is quite possible that we only need to worry when HasCollectionExpressionApplicableAddMethod
reports "error CS1950: The best overloaded Add method '{bestCandidate}' for the collection initializer has some invalid arguments"
{ | ||
if (!HasCollectionExpressionApplicableConstructor(node.Syntax, targetType, diagnostics)) | ||
{ | ||
reportedErrors = true; |
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.
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.
On the other hand, if "error CS1729: '{targetType}' does not contain a constructor that takes 0 arguments" and the like are the only errors that we can get from HasCollectionExpressionApplicableConstructor
, that is probably fine too.
This error also feels confusing #Closed Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:5830 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
This one is probably confusing too #Closed Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:6334 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
Can one call it explicitly without a modifier? In reply to: 1888571804 Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:6417 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
It looks like it is working for collection initializers, perhaps we should go along In reply to: 1889982854 Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:6417 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
{ | ||
if (!HasCollectionExpressionApplicableConstructor(node.Syntax, targetType, diagnostics)) | ||
{ | ||
reportedErrors = true; |
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.
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.
Yes, there are several tests that hit this with a type parameter, including TypeParameter_03
.
It feels like this information is useful for a user #Closed Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:7496 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
This is probably confusing too #Closed Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:25282 in 1ad210c. [](commit_id = 1ad210c, deletion_comment = False) |
Done with review pass (commit 3). I think the error reporting should be improved. At the moment, I am not sure about the implementation strategy for that. It is quite possible that the most reliable way is to have overload resolution report errors in a special mode for the two interesting call sites. Basically never report specific confusing errors and report other errors instead. |
Thanks. I'll consider potentially for a subsequent change. Presumably, it would require checking for In reply to: 1899196694 Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:3783 in 559c4fc. [](commit_id = 559c4fc, deletion_comment = 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 13)
Sorry, I realize it wouldn't help here, but I was proposing to modify the error message you're adding: In reply to: 1899232311 Refers to: src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs:3783 in 559c4fc. [](commit_id = 559c4fc, deletion_comment = 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 Thanks (iteration 13)
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 15), I assume more changes are coming to this PR
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 Thanks (iteration 15)
@cston It looks like there are legitimate test failures |
|
||
internal bool HasCollectionExpressionApplicableAddMethod(SyntaxNode syntax, TypeSymbol targetType, TypeSymbol elementType, ImmutableArray<BoundNode> elements, BindingDiagnosticBag diagnostics) | ||
{ | ||
if (elements.Length == 0) |
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.
Done with review pass (commit 19) |
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 20)
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 Thanks (iteration 20)
See corresponding spec changes dotnet/csharplang#7802 and dotnet/csharplang#7873.
Relates to test plan #66418