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

Avoid reporting ref safety errors for discard assignments #65693

Merged
merged 6 commits into from
Dec 20, 2022

Conversation

cston
Copy link
Member

@cston cston commented Dec 1, 2022

Fixes #65522
Fixes #65651

Also fixes an additional issue where the compiler was reporting a ref safety error for deconstruction into an explicitly typed discard - see RefEscapingTests.Discard_03:

(var x3, R _) = F(); // error CS8350: ... may expose variables referenced by parameter 'y' ...

ref struct R 
{
    public void Deconstruct(out R x, out R y) => throw null;
}

@cston cston force-pushed the 65651 branch 5 times, most recently from 1bccb86 to d1f345d Compare December 5, 2022 00:06
@cston cston marked this pull request as ready for review December 5, 2022 01:36
@cston cston requested a review from a team as a code owner December 5, 2022 01:36
@@ -182,7 +182,7 @@ internal override BoundStatement BindForEachDeconstruction(BindingDiagnosticBag
ExpressionSyntax variables = ((ForEachVariableStatementSyntax)_syntax).Variable;

// Tracking narrowest safe-to-escape scope by default, the proper val escape will be set when doing full binding of the foreach statement
var valuePlaceholder = new BoundDeconstructValuePlaceholder(_syntax.Expression, variableSymbol: null, this.LocalScopeDepth, inferredType.Type ?? CreateErrorType("var"));
var valuePlaceholder = new BoundDeconstructValuePlaceholder(_syntax.Expression, variableSymbol: null, this.LocalScopeDepth, isDiscardExpression: false, inferredType.Type ?? CreateErrorType("var"));
Copy link
Member

@jcouv jcouv Dec 8, 2022

Choose a reason for hiding this comment

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

false

I didn't follow this. It should be possible to have a discard in a deconstruction-foreach
Comment also applies to line 358 below #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I believe this placeholder is for the expression rather than iteration variables.

{
static void F(ref R r)
{
foreach ((R r0, _) in new Enumerable1()) break;
Copy link
Member

@jcouv jcouv Dec 8, 2022

Choose a reason for hiding this comment

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

Consider adding a non-deconstruction variant: foreach (var _ in ...) or foreach (ref var _ in ...) #Closed

Copy link
Member

Choose a reason for hiding this comment

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

Also, I liked how for deconstruction tests you added the equivalent lowered version (calling Deconstruct). Consider doing the same for foreach-deconstruction scenarios, adding equivalent lowered code.

Copy link
Member

@jcouv jcouv left a 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 (iteration 4)

@jcouv jcouv self-assigned this Dec 8, 2022
Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM Thanks (iteration 6)

@cston cston requested review from RikkiGibson and a team December 13, 2022 20:42
@RikkiGibson RikkiGibson self-assigned this Dec 13, 2022
@cston cston merged commit 34180c3 into dotnet:main Dec 20, 2022
@cston cston deleted the 65651 branch December 20, 2022 00:09
@ghost ghost added this to the Next milestone Dec 20, 2022
@Cosifne Cosifne modified the milestones: Next, 17.5 P3 Jan 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants