Skip to content

Conversation

@RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Sep 30, 2022

Closes #64394
Closes #22361

@ghost ghost added the Area-Compilers label Sep 30, 2022
@RikkiGibson RikkiGibson marked this pull request as ready for review October 4, 2022 17:39
@RikkiGibson RikkiGibson requested a review from a team as a code owner October 4, 2022 17:39
@RikkiGibson RikkiGibson marked this pull request as draft October 4, 2022 20:47
BoundLocal { DeclarationKind: not BoundLocalDeclarationKind.None } l => l.ExpressionSymbol,
_ => null
};
if (symbol is SourceLocalSymbol { ValEscapeScope: CallingMethodScope } local)
Copy link
Member Author

@RikkiGibson RikkiGibson Oct 6, 2022

Choose a reason for hiding this comment

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

note that we really would prefer to use a sentinel ValEscapeScope in cases like these (e.g. with value 1 << 32). I attempted to do this but it started to really churn and wanted to be expedient for the purposes of getting this fix in.

@RikkiGibson RikkiGibson changed the base branch from release/dev17.4 to main October 6, 2022 22:15
// e.g. in `dest = M(ref arg)`, we assume `ref arg` will not escape into `dest`, but `arg` might.
inferredDestinationValEscape = Math.Max(inferredDestinationValEscape, GetValEscape(argument, scopeOfTheContainingExpression));
var valid = CheckValEscape(argument.Syntax, argument, scopeOfTheContainingExpression, escapeTo, false, diagnostics);

Copy link
Contributor

Choose a reason for hiding this comment

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

receiver: null, // receiver handled explicitly below

Note: We also pass receiver: null in GetInvocationEscapeScope() and CheckInvocationEscape(). I think it's reasonable to keep those callers as is for now, but mentioning it in case I've overlooked something.

&& isMixableParameter(parameter)
// assume any expression variable is a valid mixing destination,
// since we will infer a legal val-escape for it (if it doesn't already have a narrower one).
&& !ShouldInferDeclarationExpressionValEscape(argument, out _))
Copy link
Member

Choose a reason for hiding this comment

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

I don't think ShouldInferDeclarationExpressionValEscape is the best call here. Consider in the future if we actually did the change where we checked if it had been previously inferred. At that point I would expect Should to return false as we've already inferred the value.

Wouldn't it be more correct to change isMixableParameter to just return false for any declaration expression? Those are not mixable parameters because they're completely inferred.

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 thought this through a bit, and yeah, I don't think there are any scenarios where a declaration variable needs to be checked as a mixing destination, since either:

  1. it is an out var at the top level of a script, therefore is a class field, therefore its type will never be ref struct
  2. it is a out scoped var in which case the val-escape is the narrowest which is even permitted to be referenced at that location.
  3. it is a regular out var in which case the widest legal val-escape is inferred for it.

Comment on lines +2314 to 2320
foreach (var (_, argument, _) in escapeArguments)
{
if (ShouldInferDeclarationExpressionValEscape(argument, out var localSymbol))
{
localSymbol.SetValEscape(inferredDestinationValEscape);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This code is the same between new and updated rules. Should it be factored otu?

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 think it is just beneath the bar of factoring out.

static RS M2(ref RS rs5)
{
// RSTE of rs3 is ReturnOnly.
Copy link
Contributor

Choose a reason for hiding this comment

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

rs3

rs5

@RikkiGibson RikkiGibson merged commit f67b176 into dotnet:main Oct 10, 2022
@RikkiGibson RikkiGibson deleted the decl-expression-scope branch October 10, 2022 23:29
@ghost ghost added this to the Next milestone Oct 10, 2022
RikkiGibson added a commit to RikkiGibson/roslyn that referenced this pull request Oct 10, 2022
{
foreach (var (_, argument, refKind) in escapeArguments)
{
if (ShouldInferDeclarationExpressionValEscape(argument, out _))
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 think we also wanted to change this to use 'isMixableArgument'.

I think the behavior/factoring for the current release is going to be fine, we just want to make sure to iron these kinds of things out when we refactor in 17.5.

jcouv added a commit that referenced this pull request Oct 11, 2022
cston added a commit to cston/roslyn that referenced this pull request Oct 11, 2022
cston added a commit that referenced this pull request Oct 11, 2022
Revert: Revert "Set val escape on expression variables (#64414)"

Co-authored-by: Rikki Gibson <rigibson@microsoft.com>
RikkiGibson added a commit to RikkiGibson/roslyn that referenced this pull request Oct 11, 2022
Revert: Revert "Set val escape on expression variables (dotnet#64414)"

Co-authored-by: Rikki Gibson <rigibson@microsoft.com>
RikkiGibson added a commit that referenced this pull request Oct 12, 2022
@RikkiGibson RikkiGibson modified the milestones: Next, 17.5 P1 Oct 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect scoped lifetime inference for out locals Out vars should get their safe-to-escape scope from their declaring expression

3 participants