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

No error reported assigning through ref local of ref struct type after ref assigning parameter #62618

Closed
cston opened this issue Jul 13, 2022 · 6 comments · Fixed by #64561
Closed

Comments

@cston
Copy link
Member

cston commented Jul 13, 2022

An escape error should be reported for the rL = local assignment.

No errors are reported, with or without -langversion:11.

using System;

class Program
{
    static void Main()
    {
        Span<int> s = new[] { 1 };
        M(ref s);
    }

    static void M(ref Span<int> s)
    {
        Span<int> local = stackalloc int[] { 1 };
        ref Span<int> rL = ref local;
        rL = ref s;
        rL = local; // expected error
    }
}
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Jul 13, 2022
@cston
Copy link
Member Author

cston commented Jul 13, 2022

cc @agocke, @jaredpar

@cston cston self-assigned this Jul 13, 2022
@cston cston changed the title No error reported assigning through ref local of ref struct type initialized with ref parameter No error reported assigning through ref local of ref struct type after ref assigning parameter Jul 13, 2022
@RikkiGibson
Copy link
Contributor

RikkiGibson commented Jul 13, 2022

Is this the result of a spec bug? Or is it strictly an implementation bug?

@jaredpar
Copy link
Member

It's an implementation bug.

@agocke
Copy link
Member

agocke commented Jul 13, 2022

I would actually expect the error on this line:

rL = ref s;

AFAIK ref-reassignment doesn't change the lifetime of the variable, and the value assignment below is an assignment of a local lifetime to a ref local lifetime. It's the conversion of outer ref to local ref in the value position (i.e. the T in ref T) that I think is the safety issue.

@jaredpar
Copy link
Member

We were looking through the span safety rules and they just seem to miss this case. This is the rule for ref reassignment:

For a ref reassignment e1 = ref e2, the ref-safe-to-escape of e2 must be at least as wide a scope as the ref-safe-to-escape of e1.

This is effectively encoding that the scope of a ref can be made smaller with a ref reassignment but not bigger. That is correct but it misses the fact that the lifetime of the value pointed to by the ref must be invariant with respect to the ref. There is nothing capturing that in the rule. It should read

For a ref reassignment e1 = ref e2, the ref-safe-to-escape of e2 must be at least as wide a scope as the ref-safe-to-escape of e1 and the safe-to-escape of e1 must be the same safe-to-escape as e2

As such I agree the error is on the line rl = ref s;. That is where the error is.

@agocke
Copy link
Member

agocke commented Jul 13, 2022

Agreed, that's precisely the spec change I'd make as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants