Skip to content

Incorrect lifetime reported for using local #85694

Description

@hamarb123

Version Used: .NET SDK 10.0.401

Steps to Reproduce:

using System;
using System.Diagnostics.CodeAnalysis;

public struct S : IDisposable
{
    [UnscopedRef]
    public ref S Self => ref this;

    public void Dispose() { }

    public S X() => new();
}

public class C
{
    public static void X1(ref S s)
    {
        using var a = s.X();
        using var b = s.X();

        ref var c = ref a.Self;
        if ("1" == 1.ToString()) c = ref b.Self; // No CS8374
    }

    public static void X2(ref S s)
    {
        using var a = s.X();
        using var b = s.X();

        ref var c = ref a.Self;
        if ("1" == 1.ToString())
        {
            c = ref b.Self; // CS8374
        }
    }

    public static void X3(ref S s)
    {
        using var a = s.X();
        using var b = s.X();

        ref var c = ref b.Self;
        if ("1" == 1.ToString())
        {
            c = ref a.Self; // CS8374
        }
    }
}

Godbolt

.NET Lab

Diagnostic Id:

CS8374: Cannot ref-assign 'b.Self' to 'c' because 'b.Self' has a narrower escape scope than 'c'.
CS8374: Cannot ref-assign 'a.Self' to 'c' because 'a.Self' has a narrower escape scope than 'c'.

Expected Behavior:

Compiles without error - this would match what the lifetimes are. Or potentially, only one of the X2 and X3 ordering works if you consider a and b to have slightly different lifetime scopes due to using effectively translating to a try/finally - although, I am not sure that this can actually ever make a difference here (ito blocking something actually unsafe) (I suspect not, but haven't thought about it super hard) (regardless, even if this were the case, then X3 should still compile as can be seen in https://godbolt.org/z/bPYsd53Te, and it certainly shouldn't depend on whether I put the assignment into a block or inline statement).

Actual Behavior:

X1 compiles fine, but X2 and X3 have errors. If you change them from using locals to normal locals, or if you change it to ref readonly var c = ... and from ref S Self to readonly ref readonly S Self, then it compiles.

/cc @jaredpar @jjonescz

Activity

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

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions