Case where old extensions cannot be converted to new extensions due to overloading by `ref`
Version Used: .NET Lab & Godbolt
Steps to Reproduce:
Old version:
public static class A
{
public static void M<T>(this T value) where T : class { }
public static void M<T>(this ref T value) where T : struct { }
}
New version:
public static class B
{
extension<T>(T inst) where T : class
{
public void M() { }
}
extension<T>(ref T inst) where T : struct
{
public void M() { }
}
}
Diagnostic Id: error CS0111: Type 'B' already defines a member called 'M' with the same parameter types
Expected Behavior: Compiles since they get lowered to methods that don't conflict in IL, and it worked previously.
Actual Behavior: Does not compile, so cannot convert into the new extension style.
@jcouv
From discussion with extensions WG 2025-06-27, we're planning to adjust the conflict rules to account for CLR-level constraints (ie. constraints minus notnull, tuple names and nullability annotation). That should fix this scenario
This was fixed and verified by the following test:
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/79043")]
public void MemberNameAndSignatureConflict_35()
{
var src = """
new object().M();
int i = 42;
i.M();
public static class C
{
extension<T>(T inst) where T : class
{
public void M() { System.Console.Write("ran1 "); }
}
extension<T>(ref T inst) where T : struct
{
public void M() { System.Console.Write("ran2"); }
}
}
""";
var comp = CreateCompilation(src);
CompileAndVerify(comp, expectedOutput: "ran1 ran2").VerifyDiagnostics();
}
Closing as fixed. Thanks for reporting this!