Skip to content

Assertion in ref analysis of deconstruction with extension and array to span conversion on receiver #78682

@jcouv

Description

@jcouv

The test below results in an assertion.
The generated IL looks good as far as I can tell and executes properly (lab)

This issue also affects new extension methods. It is referenced in a test.

    [Fact]
    public void TODO2()
    {
        // array to Span
        var src = """
var (x, y) = new int[] { 42 };
System.Console.Write((x, y));

static class E
{
    public static void Deconstruct(this System.Span<int> s, out int i, out int j) { i = 42; j = 43; }
}
""";
        var comp = CreateCompilation(src, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: "(42, 43)").VerifyDiagnostics();
    }
  Message: 
System.InvalidOperationException : Expected Microsoft.CodeAnalysis.CSharp.BoundConversion `var (x, y) = new int[] { 42 }` to be visited.

  Stack Trace: 
ThrowingTraceListener.Fail(String message, String detailMessage) line 26
TraceInternal.Fail(String message, String detailMessage)
Debug.Fail(String message, String detailMessage)
RoslynDebug.Assert(Boolean condition, AssertInterpolatedStringHandler& message) line 30
RefSafetyAnalysis.AssertVisited(BoundExpression expr) line 299
RefSafetyAnalysis.GetValEscape(BoundExpression expr, SafeContext localScopeDepth) line 4126
RefSafetyAnalysis.<CheckInvocationArgMixingWithUpdatedRules>g__inferDeclarationExpressionValEscape|31_0(<>c__DisplayClass31_0&) line 3042
RefSafetyAnalysis.CheckInvocationArgMixingWithUpdatedRules(SyntaxNode syntax, MethodInfo& methodInfo, BoundExpression receiverOpt, ThreeState receiverIsSubjectToCloning, ImmutableArray`1 parameters, ImmutableArray`1 argsOpt, ImmutableArray`1 argRefKindsOpt, ImmutableArray`1 argsToParamsOpt, SafeContext localScopeDepth, BindingDiagnosticBag diagnostics, Symbol symbolForReporting) line 3029
RefSafetyAnalysis.CheckInvocationArgMixing(SyntaxNode syntax, MethodInfo& methodInfo, BoundExpression receiverOpt, ThreeState receiverIsSubjectToCloning, ImmutableArray`1 parameters, ImmutableArray`1 argsOpt, ImmutableArray`1 argRefKindsOpt, ImmutableArray`1 argsToParamsOpt, SafeContext localScopeDepth, BindingDiagnosticBag diagnostics) line 2876
RefSafetyAnalysis.VisitDeconstructionArguments(ArrayBuilder`1 variables, SyntaxNode syntax, Conversion conversion, BoundExpression right) line 1030
[...]

Note that invocation of such an extension method doesn't suffer from this problem:

    [Fact]
    public void Works()
    {
        var src = """
new int[] { 42 }.M(out var x, out var y);
System.Console.Write((x, y));

static class E
{
    public static void M(this System.Span<int> s, out int i, out int j) { i = 42; j = 43; }
}
""";
        var comp = CreateCompilation(src, targetFramework: TargetFramework.Net90);
        CompileAndVerify(comp, expectedOutput: "(42, 43)").VerifyDiagnostics();
    }

Metadata

Metadata

Assignees

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions