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
Version Used: .NET SDK 10.0.401
Steps to Reproduce:
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
X2andX3ordering works if you consideraandbto have slightly different lifetime scopes due tousingeffectively translating to atry/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, thenX3should 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:
X1compiles fine, butX2andX3have errors. If you change them fromusinglocals to normal locals, or if you change it toref readonly var c = ...and fromref S Selftoreadonly ref readonly S Self, then it compiles./cc @jaredpar @jjonescz