-
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
Handle capturing of primary constructor parameters within queries and in type-or-value scenarios #66254
Handle capturing of primary constructor parameters within queries and in type-or-value scenarios #66254
Conversation
} | ||
|
||
this.LookupExtensionMethodsInSingleBinder(scope, lookupResult, rightName, arity, options, ref useSiteInfo); | ||
return useSiteInfo; |
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.
The return value of this method is never used?
Yes. This is an artifact of an automatic refactoring. Will fix.
captured.Free(); | ||
|
||
return _capturedParameters; | ||
throw ExceptionUtilities.Unreachable(); |
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.
} | ||
|
||
[Fact] | ||
public void ParameterCapturing_022_ColorColor_MemberAccess_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.
Diagnostic(ErrorCode.WRN_UnreadRecordParameter, "Color").WithArguments("Color").WithLocation(2, 17), | ||
// (4,33): error CS9500: Cannot use primary constructor parameter 'Color Color' in this context. | ||
// public static int Test() => Color.M1(new S1()); | ||
Diagnostic(ErrorCode.ERR_InvalidPrimaryConstructorParameterReference, "Color").WithArguments("Color Color").WithLocation(4, 33) |
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.
This error feels unexpected. The parameter is not used here. I would expect this code to compile and call the static method.
Language rules do not agree with these expectations
https://sharplab.io/#v2:C4LglgNgPgzsBOBXAxsABAZQIwFgBQA3vmiWgAIDM5WAbGmAHboAqApnABQDCA9hD/DS9+8AJRoAvAD4hfAQDoAslg4NWAd0wrRogNz4AvvnxkATLJH4ieUuSqN0yjtjQAPcdLQAGfTdLFSSmo6BzRlAB5mKQ5mN3F1AAtWeFY0WJA0RAYAWwBDBlyAc1YAE0kZH0N8IA===
struct S1
{
public static int Test(Color Color) => Color.M1(new S1());
}
class Color
{
public int M1(S1 x) => 0;
public static int M1<T>(T x) where T : unmanaged => 0;
}
Observed:
.method public hidebysig static
int32 Test (
class Color Color
) cil managed
{
.custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x20a0
// Code size 16 (0x10)
.maxstack 2
.locals init (
[0] valuetype S1
)
IL_0000: ldarg.0
IL_0001: ldloca.s 0
IL_0003: initobj S1
IL_0009: ldloc.0
IL_000a: callvirt instance int32 Color::M1(valuetype S1)
IL_000f: ret
} // end of method S1::Test
comp.VerifyEmitDiagnostics( | ||
// (6,19): error CS0229: Ambiguity between 'Color.P' and 'Color.P' | ||
// _ = Color.P; | ||
Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("Color.P", "Color.P").WithLocation(6, 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.
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'm curious why this also isn't
ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver
?
Because lookup fails with the ERR_AmbigMember
, C# doesn't support overloading of regular properties. The ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver
is reported if lookup succeeds
@cston, @dotnet/roslyn-compiler For the second review |
(object)contaningMember.ContainingSymbol != primaryCtor.ContainingSymbol || // The member doesn't belong to our type, i.e. from nested type | ||
((object)contaningMember != primaryCtor && contaningMember is MethodSymbol { MethodKind: MethodKind.Constructor })) && // We are in a non-primary instance constructor | ||
(!IsInDeclaringTypeInstanceMember(primaryCtor) || | ||
(this.ContainingMember() is MethodSymbol { MethodKind: MethodKind.Constructor } contaningMember && (object)contaningMember != primaryCtor)) && // We are in a non-primary instance constructor |
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.
{ | ||
return !(InParameterDefaultValue || | ||
InAttributeArgument || | ||
this.ContainingMember() is not { Kind: not SymbolKind.NamedType, IsStatic: false } contaningMember || // We are not in an instance member |
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.
@@ -6390,12 +6404,17 @@ private BoundExpression BindLeftIdentifierOfPotentialColorColorMemberAccess(Iden | |||
var boundType = BindNamespaceOrType(left, typeDiagnostics); | |||
if (TypeSymbol.Equals(boundType.Type, leftType, TypeCompareKind.AllIgnoreOptions)) | |||
{ | |||
Debug.Assert(!leftType.IsDynamic()); | |||
Debug.Assert(IsPotentialColorColorReceiver(left, leftType)); |
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.
What is the assert checking? (It looks like
IsPotentialColorColorReceiver()
is checking the same two conditions as the two if conditions above.)
It is verifying that we can rely on IsPotentialColorColorReceiver
elsewhere to check for the same condition.
@@ -1564,6 +1564,27 @@ private BoundExpression ReplaceTypeOrValueReceiver(BoundExpression receiver, boo | |||
} | |||
} | |||
|
|||
private BoundExpression GetValueExpressionIfTypeOrValueReceiver(BoundExpression receiver) |
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.
diagnostics.Add(ErrorCode.ERR_FuncPtrMethMustBeStatic, location, symbol); | ||
} | ||
else | ||
if (receiverOpt?.HasErrors != 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.
What is the impact of this change? Does it improve errors or does it affect non-error scenarios?
It reduces the noise in error scenarios. See the only test in QueryTests.cs, for example. However, the primary goal was to suppress cascading diagnostics on a BoundBadExpression that we create in ConstructBoundMemberGroupAndReportOmittedTypeArguments
due to an ambiguity.
|
||
LookupOptions options = LookupOptions.AllMethodsOnArityZero; | ||
if (SyntaxFacts.IsInvoked(id)) | ||
bool checkQuery(QueryExpressionSyntax query, Binder enclosingBinder) |
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 this test identical to In reply to: 1375123522 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:9677 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Why is In reply to: 1375131340 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10284 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Why is In reply to: 1375132933 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10315 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Consider including capture of an unmanaged parameter:
In reply to: 1375136132 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10728 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
It looks like both properties are instance members. In reply to: 1375136996 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10829 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Why isn't this ambiguous? In reply to: 1375138681 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10872 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Looks like it is. I'll remove it. In reply to: 1375123522 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:9677 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
Initializer value is not a capturing context, therefore the ambiguity restriction doesn't apply. Here is one of the conditions from the spec: "If In reply to: 1375131340 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10284 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
What argument mismatch? Regardless, the ambiguity rule doesn't take arguments into consideration at all. See dotnet/csharplang#6855. In reply to: 1375132933 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10315 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
There are no static methods. Per spec: "Extension methods applicable to the receiver type are treated as instance methods for the purpose of this check." The "Color" definetly won't be valid as a type. In reply to: 1375138681 Refers to: src/Compilers/CSharp/Test/Semantic/Semantics/PrimaryConstructorTests.cs:10872 in 808952a. [](commit_id = 808952a, deletion_comment = False) |
The first parameter in the instance method is declared as
|
Thanks for pointing this out. I will adjust this in one of the next PRs In reply to: 1376143344 |
This PR matches the version of the spec from dotnet/csharplang#6855.
It might be easier to review commit by commit.