@@ -3867,6 +3867,9 @@ .method public hidebysig static void M<class T> () cil managed
38673867 // (1,5): error CS0570: 'E.extension(int).M<T>()' is not supported by the language
38683868 // int.M();
38693869 Diagnostic(ErrorCode.ERR_BindToBogus, "M").WithArguments("E.extension(int).M<T>()").WithLocation(1, 5));
3870+
3871+ var method = comp.GlobalNamespace.GetTypeMember("E").GetTypeMembers().Single().GetMember<MethodSymbol>("M").GetPublicSymbol();
3872+ Assert.Null(method.AssociatedExtensionImplementation);
38703873 }
38713874
38723875 [Fact]
@@ -33081,8 +33084,7 @@ public void M() { }
3308133084 var model = comp.GetSemanticModel(tree);
3308233085 var memberAccess = GetSyntax<MemberAccessExpressionSyntax>(tree, "42.M");
3308333086 var method = (IMethodSymbol)model.GetSymbolInfo(memberAccess).Symbol;
33084- // Tracked by https://github.com/dotnet/roslyn/issues/78957 : public API, add support for constructed symbols
33085- Assert.Null(method.AssociatedExtensionImplementation);
33087+ AssertEx.Equal("void E.M<System.Int32>(this System.Int32 t)", method.AssociatedExtensionImplementation.ToTestDisplayString());
3308633088 Assert.Equal("void E.M<T>(this T t)", method.OriginalDefinition.AssociatedExtensionImplementation.ToTestDisplayString());
3308733089 }
3308833090
@@ -33188,6 +33190,151 @@ .method family hidebysig static void M () cil managed
3318833190 Assert.Null(method.AssociatedExtensionImplementation);
3318933191 }
3319033192
33193+ [Fact]
33194+ public void AssociatedExtensionImplementation_06()
33195+ {
33196+ // not a definition, generic extension and method
33197+ var src = """
33198+ 42.M(43L, "");
33199+
33200+ public static class E
33201+ {
33202+ extension<T>(T t)
33203+ {
33204+ public void M<U, V>(U u, V v) { }
33205+ }
33206+ }
33207+ """;
33208+ var comp = CreateCompilation(src);
33209+ comp.VerifyEmitDiagnostics();
33210+
33211+ var tree = comp.SyntaxTrees.First();
33212+ var model = comp.GetSemanticModel(tree);
33213+ var memberAccess = GetSyntax<MemberAccessExpressionSyntax>(tree, "42.M");
33214+ var method = (IMethodSymbol)model.GetSymbolInfo(memberAccess).Symbol;
33215+ AssertEx.Equal("void E.M<System.Int32, System.Int64, System.String>(this System.Int32 t, System.Int64 u, System.String v)",
33216+ method.AssociatedExtensionImplementation.ToTestDisplayString());
33217+ }
33218+
33219+ [Fact]
33220+ public void AssociatedExtensionImplementation_07()
33221+ {
33222+ // generic definition
33223+ var src = """
33224+ public static class E
33225+ {
33226+ extension<T>(T t)
33227+ {
33228+ public void M<U, V>(U u, V v)
33229+ {
33230+ t.M(u, v);
33231+ }
33232+ }
33233+ }
33234+ """;
33235+ var comp = CreateCompilation(src);
33236+ comp.VerifyEmitDiagnostics();
33237+
33238+ var tree = comp.SyntaxTrees.First();
33239+ var model = comp.GetSemanticModel(tree);
33240+ var memberAccess = GetSyntax<MemberAccessExpressionSyntax>(tree, "t.M");
33241+ var method = (IMethodSymbol)model.GetSymbolInfo(memberAccess).Symbol;
33242+ Assert.True(method.IsDefinition);
33243+ var associated = method.AssociatedExtensionImplementation;
33244+ AssertEx.Equal("void E.M<T, U, V>(this T t, U u, V v)", associated.ToTestDisplayString());
33245+ Assert.False(associated.IsDefinition);
33246+ }
33247+
33248+ [Fact]
33249+ public void AssociatedExtensionImplementation_08()
33250+ {
33251+ // not a definition, generic extension and method, partially constructed with type parameters
33252+ var src = """
33253+ public static class E
33254+ {
33255+ extension<T>(T t)
33256+ {
33257+ public void M<U, V>(U u, V v)
33258+ {
33259+ t.M(42L, "");
33260+ }
33261+ }
33262+ }
33263+ """;
33264+ var comp = CreateCompilation(src);
33265+ comp.VerifyEmitDiagnostics();
33266+
33267+ var tree = comp.SyntaxTrees.First();
33268+ var model = comp.GetSemanticModel(tree);
33269+ var memberAccess = GetSyntax<MemberAccessExpressionSyntax>(tree, "t.M");
33270+ var method = (IMethodSymbol)model.GetSymbolInfo(memberAccess).Symbol;
33271+ AssertEx.Equal("void E.M<T, System.Int64, System.String>(this T t, System.Int64 u, System.String v)",
33272+ method.AssociatedExtensionImplementation.ToTestDisplayString());
33273+ }
33274+
33275+ [Fact]
33276+ public void AssociatedExtensionImplementation_09()
33277+ {
33278+ // generic enclosing class, generic implementation method
33279+ var src = """
33280+ public static class E<T0>
33281+ {
33282+ extension<T1>(T1 t1)
33283+ {
33284+ public void M<T2>(T2 t2)
33285+ {
33286+ }
33287+ }
33288+ }
33289+ """;
33290+ var comp = CreateCompilation(src);
33291+ comp.VerifyEmitDiagnostics(
33292+ // (3,5): error CS9283: Extensions must be declared in a top-level, non-generic, static class
33293+ // extension<T1>(T1 t1)
33294+ Diagnostic(ErrorCode.ERR_BadExtensionContainingType, "extension").WithLocation(3, 5));
33295+
33296+ var extension = comp.GlobalNamespace.GetTypeMember("E").GetTypeMembers("").Single();
33297+ var method = extension.GetMethod("M").GetPublicSymbol();
33298+ Assert.True(method.IsDefinition);
33299+ var associated = method.AssociatedExtensionImplementation;
33300+ AssertEx.Equal("void E<T0>.M<T1, T2>(this T1 t1, T2 t2)", associated.ToTestDisplayString());
33301+ Assert.False(associated.IsDefinition);
33302+
33303+ var e = comp.GlobalNamespace.GetTypeMember("E");
33304+ var constructedE = e.Construct(comp.GetSpecialType(SpecialType.System_Int32));
33305+ var constructedMethod = constructedE.GetTypeMembers("").Single().GetMethod("M").GetPublicSymbol();
33306+ AssertEx.Equal("void E<System.Int32>.<G>$8048A6C8BE30A622530249B904B537EB<T1>.M<T2>(T2 t2)", constructedMethod.ToTestDisplayString());
33307+ AssertEx.Equal("void E<System.Int32>.M<T1, T2>(this T1 t1, T2 t2)", constructedMethod.AssociatedExtensionImplementation.ToTestDisplayString());
33308+ }
33309+
33310+ [Fact]
33311+ public void AssociatedExtensionImplementation_10()
33312+ {
33313+ // generic enclosing class, non-generic implementation method
33314+ var src = """
33315+ public static class E<T0>
33316+ {
33317+ extension(int i)
33318+ {
33319+ public void M()
33320+ {
33321+ }
33322+ }
33323+ }
33324+ """;
33325+ var comp = CreateCompilation(src);
33326+ comp.VerifyEmitDiagnostics(
33327+ // (3,5): error CS9283: Extensions must be declared in a top-level, non-generic, static class
33328+ // extension<T1>(T1 t1)
33329+ Diagnostic(ErrorCode.ERR_BadExtensionContainingType, "extension").WithLocation(3, 5));
33330+
33331+ var e = comp.GlobalNamespace.GetTypeMember("E");
33332+ var constructedE = e.Construct(comp.GetSpecialType(SpecialType.System_Int32));
33333+ var constructedMethod = constructedE.GetTypeMembers("").Single().GetMethod("M").GetPublicSymbol();
33334+ AssertEx.Equal("void E<System.Int32>.<G>$BA41CFE2B5EDAEB8C1B9062F59ED4D69.M()", constructedMethod.ToTestDisplayString());
33335+ AssertEx.Equal("void E<System.Int32>.M(this System.Int32 i)", constructedMethod.AssociatedExtensionImplementation.ToTestDisplayString());
33336+ }
33337+
3319133338 [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78606")]
3319233339 public void DocumentationCommentId_01()
3319333340 {
0 commit comments