-
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
Support ref struct implementing interfaces in foreach
and using
statements
#72810
Support ref struct implementing interfaces in foreach
and using
statements
#72810
Conversation
1 similar comment
|
||
if (unwrappedCollectionExprType.IsRefLikeType || unwrappedCollectionExprType is TypeParameterSymbol { AllowByRefLike: true }) | ||
{ | ||
builder.CollectionType = unwrappedCollectionExprType; |
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 the spec-let update the foreach statement definition of collection type for ref struct
and allows ref struct
cases?
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.CollectionType
Should the spec-let update the definition of collection type for
ref struct
andallows ref struct
cases?
Could you elaborate please? What are you suggesting to modify and where?
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 dotnet/csharplang#8024 include a section that updates the foreach statement definition to indicate the expected collection type, etc. for ref struct
cases and type parameters with allows ref struct
? Currently, the existing spec section seems to indicate the collection type will be IEnumerable<T>
or IEnumerable
. Are those correct, given how collection type, etc. is used in the foreach
expansion and perhaps elsewhere?
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 dotnet/csharplang#8024 include a section that updates the foreach statement definition to indicate the expected collection type, etc. for
ref struct
cases and type parameters withallows ref struct
? Currently, the existing spec section seems to indicate the collection type will beIEnumerable<T>
orIEnumerable
. Are those correct, given how collection type, etc. is used in theforeach
expansion and perhaps elsewhere?
I am satisfied with how dotnet/csharplang#8024 specifies the expected behavior. I will mention that foreach statement will have to be adjusted accordingly. However, I prefer leaving this exercise for later and quite possibly for the one changing the official spec.
@@ -1482,6 +1484,13 @@ public BoundExpression Convert(TypeSymbol type, BoundExpression arg) | |||
CompoundUseSiteInfo<AssemblySymbol>.Discarded; | |||
#endif | |||
Conversion c = Compilation.Conversions.ClassifyConversionFromExpression(arg, type, isChecked: false, ref useSiteInfo); | |||
|
|||
if (allowBoxingByRefLikeTypeParametersToObject && !c.Exists && |
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.
allowBoxingByRefLikeTypeParametersToObject
When is it valid to allowing boxing?
// The code boxes type parameter that allows ref struct, however 'box' followed by 'brfalse' is
// documented as a valid sequence at https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md#special-il-sequences
//
// IL_000b: ldloc.0
// IL_000c: box ""T""
// IL_0011: brfalse.s IL_0020
{ | ||
LazyAsyncMethodChecks(CancellationToken.None); | ||
Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks)); | ||
} |
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.
Was this incorrect?
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.
Was this incorrect?
It was done too early. Apparently, for no good reason. Was causing a cycle because the check needs to access constraints, which this method is responsible to figure out in case of overriding.
|
||
if (unwrappedCollectionExprType.IsRefLikeType || unwrappedCollectionExprType is TypeParameterSymbol { AllowByRefLike: true }) | ||
{ | ||
builder.CollectionType = unwrappedCollectionExprType; |
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 feels fragile. We change builder.CollectionType
but below we continue to use the old NamedTypeSymbol collectionType = (NamedTypeSymbol)builder.CollectionType;
. Perhaps this whole if
could be at the end of the method instead?
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 feels fragile. We change
builder.CollectionType
but below we continue to use the oldNamedTypeSymbol collectionType = (NamedTypeSymbol)builder.CollectionType;
. Perhaps this wholeif
could be at the end of the method instead?
I do not find this too fragile. Also, there are early returns from the if
below. Therefore, I prefer to leave the code as is.
b0251c2
into
dotnet:features/RefStructInterfaces
Corresponding spec update - dotnet/csharplang#8024