-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Extensions: Address follow-ups related to collection expressions #79877
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
Conversation
| { | ||
| if (member.TryGetCorrespondingExtensionImplementationMethod() is { } extensionImplementation) | ||
| { | ||
| member = extensionImplementation; |
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.
📝 since we swap the implementation method for the member here and reduce it below, I had to relax the assertion in TypeMap again (see PR)
An alternative would be to implement the logic for this method specially for new extension methods, instead of using the implementation method to leverage the existing handling
01c628c to
083fbaa
Compare
083fbaa to
03e8cbd
Compare
| { | ||
| // If the method is generic, skip it if the type arguments cannot be inferred. | ||
| var member = candidate.Member; | ||
| if (member.GetIsNewExtensionMember()) |
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.
| builder: out var builder); | ||
| // Collection expression target types require instance method GetEnumerator. | ||
| if (result && builder.ViaExtensionMethod) // Tracked by https://github.com/dotnet/roslyn/issues/78960: Add test coverage for new extensions | ||
| if (result && builder.ViaExtensionMethod) |
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, see getEnumeratorInfo
if (SatisfiesGetEnumeratorPattern(syntax, collectionSyntax, ref builder, collectionExpr, isAsync, viaExtensionMethod: true, diagnostics))
{
return createPatternBasedEnumeratorResult(ref builder, collectionExpr, isAsync, viaExtensionMethod: true, diagnostics);
}
The relevant test is CollectionExpression_09
| { | ||
| return ConsiderEverything; | ||
| } | ||
| else if (comparison == TypeCompareKind.AllIgnoreOptions) |
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.
I prefer to remove since not exercised
| { | ||
| // mapping contents are read-only hereafter | ||
| Debug.Assert(allowAlpha || !from.Any(static tp => tp is SubstitutedTypeParameterSymbol)); | ||
| Debug.Assert(allowAlpha || !from.Any(static tp => tp is SubstitutedTypeParameterSymbol && tp.ContainingSymbol is not SourceExtensionImplementationMethodSymbol)); |
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.
| (type, parameter, unused) => type.TypeKind == TypeKind.TypeParameter && (parameter is null || TypeSymbol.Equals(type, parameter, TypeCompareKind.ConsiderEverything2)); | ||
|
|
||
| public static bool ContainsTypeParameter(this TypeSymbol type, MethodSymbol parameterContainer) | ||
| public static bool ContainsTypeParameter(this TypeSymbol type, Symbol parameterContainer) |
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.
| // (7,26): error CS1929: 'MyCollection<object>' does not contain a definition for 'Add' and the best extension method overload 'E.extension<T>(MyCollection<T>).Add(T)' requires a receiver of type 'MyCollection<T>' | ||
| // MyCollection<object> c = [oNull, oNotNull]; | ||
| Diagnostic(ErrorCode.ERR_BadInstanceArgType, "[oNull, oNotNull]").WithArguments("MyCollection<object>", "Add", "E.extension<T>(MyCollection<T>).Add(T)", "MyCollection<T>").WithLocation(7, 26)); | ||
| comp.VerifyEmitDiagnostics(); |
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.
| } | ||
| } | ||
|
|
||
| public class D : System.Collections.IEnumerable |
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.
| { | ||
| extension(C c) | ||
| { | ||
| public int Length => 2; |
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 2) |
| } | ||
| """; | ||
| var comp = CreateCompilationWithIL(src, ilSrc); | ||
| comp.VerifyEmitDiagnostics(); |
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.
Should we verify execution to check that E2 was used, not E? #Resolved
| """; | ||
| var comp = CreateCompilation(src); | ||
| comp.VerifyEmitDiagnostics( | ||
| // (1,7): error CS1921: The best overloaded method match for 'E.extension(C).Add(int)' has wrong signature for the initializer element. The initializable Add must be an accessible instance method. |
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 error wording seems inaccurate - the Add can be an instance or extension method. But I guess that's a pre-existing issue. #WontFix
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.
Yup. I'll leave as pre-existing issue
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 4)
Closes #78960
The first commit addresses minor post-PR-merge follow-ups from last PR: #79702 (comment)
The design needs to be confirmed with LDM, it is outlined here and copied below:
Note: the last LDM decision regarding pattern-based constructs was to not let extension properties count as "countable properties" in any of the relevant scenarios (list-patterns and implicit indexers) so I kept that behavior here as well.
Relates to test plan #76130