Skip to content

Nullable value type receiver of a constrained call is unexpectedly copied #66162

@AlekseyTs

Description

@AlekseyTs
        [Fact]
        public void GenericTypeParameterAsReceiver_Call_Nullable()
        {
            var source = @"
using System;

#pragma warning disable CS0659 // 'Item' overrides Object.Equals(object o) but does not override Object.GetHashCode()
    
struct Item
{
    public int Count;

    public override bool Equals(object obj)
    {
        Console.WriteLine(""Position Equals for item '{0}'"", Count);
        return base.Equals(obj);
    }
}

class Program
{
    static void Main()
    {
        Item? item1 = new Item {Count = 1};
        Call1(item1);
        Item? item2 = new Item {Count = 2};
        Call2(ref item2);
    }

    static void Call1<T>(T item)
    {
        item.Equals(GetOffset(ref item));
    }

    static void Call2<T>(ref T item)
    {
        item.Equals(GetOffset(ref item));
    }
    
    static int value = 0;
    static int GetOffset<T>(ref T item)
    {
        item = (T)(object)new Item {Count = --value};
        return 0;
    }
}
";
            var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: @"
Position Equals for item '-1'
Position Equals for item '-2'
").VerifyDiagnostics();
        }

Observed:

Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen.CodeGenCallTests.GenericTypeParameterAsReceiver_Call_Nullable [FAIL]
  Roslyn.Test.Utilities.ExecutionException : 
  Execution failed for assembly 'd9d40dcd-4b54-4258-8425-bf38af6ab1e7, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
  Expected: 
  Position Equals for item '-1'
  Position Equals for item '-2'
  
  Actual: Position Equals for item '1'
  Position Equals for item '2'

This is a regression from #65642

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions