Skip to content

Unexpected ref safety error in an assignment #79054

@jjonescz

Description

@jjonescz

[Fact]
public void UserDefinedBinaryOperator_RefStruct_Compound_ScopedTarget_04()
{
var source = """
public ref struct C
{
public static C operator +(scoped C left, C right) => right;
public static C X(scoped C left, C right) => right;
public static C Y(C left) => left;
public C M1(scoped C c, C c1)
{
return Y(c += c1);
}
public C M2(scoped C c, C c1)
{
return Y(c = X(c, c1));
}
}
""";
CreateCompilation(source).VerifyDiagnostics(
// (12,16): error CS8347: Cannot use a result of 'C.Y(C)' in this context because it may expose variables referenced by parameter 'left' outside of their declaration scope
// return Y(c = X(c, c1));
Diagnostic(ErrorCode.ERR_EscapeCall, "Y(c = X(c, c1))").WithArguments("C.Y(C)", "left").WithLocation(12, 16),
// (12,18): error CS8352: Cannot use variable 'scoped C c' in this context because it may expose referenced variables outside of their declaration scope
// return Y(c = X(c, c1));
Diagnostic(ErrorCode.ERR_EscapeVariable, "c = X(c, c1)").WithArguments("scoped C c").WithLocation(12, 18)
);
}

The error in the test above is unexpected. First, both M1 and M2 result in equivalent IL code, hence both should report equivalent diagnostics. Second, the assignment returns its right-hand side, so the return expression is equivalent to Y(X(c, c1)) which is ref safe.

See also #78987 (comment).

Metadata

Metadata

Assignees

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions