-
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
Specially handle more scenarios for type parameters with 'allows ref struct' constraint #73111
Specially handle more scenarios for type parameters with 'allows ref struct' constraint #73111
Conversation
…struct' constraint
@@ -2829,7 +2829,8 @@ public bool HasImplicitTypeParameterConversion(TypeParameterSymbol source, TypeS | |||
return true; | |||
} | |||
|
|||
if ((destination.TypeKind == TypeKind.TypeParameter) && | |||
if (destination is TypeParameterSymbol { AllowByRefLike: false } && | |||
!source.AllowByRefLike && |
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.
Are we testing this case?
I tried, but given the convoluted nature of the conversion classification algorithms, I was not able to find a scenario where we get here with source.AllowByRefLike
equals true
. Nevertheless, I am fairly comfortable making this change regardless of the fact.
@@ -2868,7 +2872,7 @@ private bool HasImplicitReferenceTypeParameterConversion(TypeParameterSymbol sou | |||
} | |||
|
|||
// * From T to a type parameter U, provided T depends on U. | |||
if ((destination.TypeKind == TypeKind.TypeParameter) && | |||
if (destination is TypeParameterSymbol { AllowByRefLike: 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.
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.
Why is
AllowByRefLike: false
required? Isn't it sufficient to checksource.AllowByRefLike (above)
andsource.DependsOn((TypeParameterSymbol)destination)
?
Why do you think it should be sufficient? Dependency between type parameters says nothing about their AllowByRefLike
property (dependent type parameters can have different values for it) and reference conversions do not exist for those that have AllowByRefLike: true
.
@@ -3221,8 +3225,8 @@ private bool HasImplicitBoxingTypeParameterConversion(TypeParameterSymbol source | |||
} | |||
|
|||
// SPEC: From T to a type parameter U, provided T depends on U | |||
if ((destination.TypeKind == TypeKind.TypeParameter) && | |||
source.DependsOn((TypeParameterSymbol)destination)) | |||
if (destination is TypeParameterSymbol { AllowByRefLike: false } d && |
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.
Why is
AllowByRefLike: false
required?
Same response as for the change on line 2875
// IL_0000: ldarg.0 | ||
// IL_0001: box ""U"" | ||
// IL_0006: unbox.any ""T"" | ||
// IL_000b: ret | ||
} | ||
} |
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.
Consider testing:
static U Test9<T, U>(T x)
where T : class
where U : T, allows ref struct
{
return x;
}
static U Test10<T, U>(T x)
where T : class
where U : T, allows ref struct
{
return (U)x;
}
``` #Closed
} | ||
|
||
[Fact] | ||
public void IllegalBoxing_05() |
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.
Is this distinct from
IllegalBoxing_02
?
It is true that some scenarios are duplicated (not all scenarios), but I do not mind and do not plan to make any changes because of that.
// => y.M; | ||
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Action").WithLocation(12, 14) | ||
); | ||
} |
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.
Are we testing the receiver for anonymous delegate types?
Adding a couple of tests for completeness.
// h2.M2(y); | ||
Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "y").WithArguments("S").WithLocation(15, 15) | ||
); | ||
} |
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.
Are we testing a ref struct receiver and dynamic argument?
Adding DynamicAccess_03
for completeness.
@jjonescz, @dotnet/roslyn-compiler For the second review |
{ | ||
static void Test1() | ||
{ | ||
_ = new T[] {}; |
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.
Consider testing T[][]
81992c9
into
dotnet:features/RefStructInterfaces
No description provided.