Skip to content
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

Conversation

AlekseyTs
Copy link
Contributor

@AlekseyTs AlekseyTs commented Mar 29, 2024

Corresponding spec update - dotnet/csharplang#8024

@AlekseyTs AlekseyTs requested a review from a team as a code owner March 29, 2024 19:49
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged Issues and PRs which have not yet been triaged by a lead label Mar 29, 2024
@AlekseyTs
Copy link
Contributor Author

@cston, @jjonescz, @dotnet/roslyn-compiler Please review

@AlekseyTs
Copy link
Contributor Author

@cston, @jjonescz, @dotnet/roslyn-compiler Please review

1 similar comment
@AlekseyTs
Copy link
Contributor Author

@cston, @jjonescz, @dotnet/roslyn-compiler Please review


if (unwrappedCollectionExprType.IsRefLikeType || unwrappedCollectionExprType is TypeParameterSymbol { AllowByRefLike: true })
{
builder.CollectionType = unwrappedCollectionExprType;
Copy link
Member

@cston cston Apr 2, 2024

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 foreach statement definition of collection type for ref struct and allows ref struct cases?

Copy link
Contributor Author

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 and allows ref struct cases?

Could you elaborate please? What are you suggesting to modify and where?

Copy link
Member

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?

Copy link
Contributor Author

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?

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 &&
Copy link
Member

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?

Copy link
Contributor Author

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));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this incorrect?

Copy link
Contributor Author

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;
Copy link
Member

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?

Copy link
Contributor Author

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?

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers New Feature - RefStructInterfaces untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants