From 7439390686603543590d25c7555b3f6ead3b2cf7 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Wed, 29 Apr 2020 11:20:46 -0700 Subject: [PATCH 1/6] Test that covariant returns are recognized by the compiler from metadata. --- .../Symbol/Symbols/CovariantReturnTests.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index cfb11892166a8..4f47acb33abe6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; +using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols @@ -27,6 +28,12 @@ private static void VerifyNoOverride(CSharpCompilation comp, string methodName) Assert.Null(overridden); } + private static CSharpCompilation MetadataView(CSharpCompilation comp, params MetadataReference[] references) + { + references = references.Append(comp.ToMetadataReference()); + return CreateCompilation("", references: references); + } + [Fact] public void CovariantReturns_01() { @@ -49,6 +56,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -78,6 +86,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -107,6 +116,7 @@ public class Derived : Base where T : class where U : class, T comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -137,6 +147,7 @@ public class Derived : Base where T : N comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -166,6 +177,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -195,6 +207,7 @@ public class Derived : Base where T : class where U : class, T comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -225,6 +238,7 @@ public class Derived : Base where T : N comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -254,6 +268,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -283,6 +298,7 @@ public class Derived : Base where T : class where U : class, T comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -313,6 +329,7 @@ public class Derived : Base where T : N comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -415,6 +432,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) { @@ -447,6 +465,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) { @@ -479,6 +498,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) { @@ -508,6 +528,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -699,6 +720,7 @@ public interface IIn { } comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -818,6 +840,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -908,6 +931,7 @@ public class Derived : Base comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -1030,6 +1054,7 @@ public class Derived2 : Derived comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( ); verify(comp); + verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { From 1ae37dc45d60c5a7b956a347578d1b6e545f4093 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Thu, 30 Apr 2020 11:03:23 -0700 Subject: [PATCH 2/6] Test that covariant methods imply metadata newslot and a methodimpl table entry. --- .../Emitter/Model/NamedTypeSymbolAdapter.cs | 5 +- .../OverriddenOrHiddenMembersHelpers.cs | 8 +- .../Symbol/Symbols/CovariantReturnTests.cs | 108 ++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/NamedTypeSymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/NamedTypeSymbolAdapter.cs index e7ade4af9c658..cf5c26f84d00b 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/NamedTypeSymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/NamedTypeSymbolAdapter.cs @@ -348,8 +348,11 @@ internal virtual IEnumerable GetEventsToEmit() // If C# and the runtime don't agree on the overridden method, then // we will mark the method as newslot (see MethodSymbolAdapter) and // specify the override explicitly. - // This mostly affects accessors - C# ignores method interactions + // This affects accessors - C# ignores method interactions // between accessors and non-accessors, whereas the runtime does not. + // It also affects covariant returns - C# ignores the return type in + // determining if one method overrides another, while the runtime considers + // the return type part of the signature. yield return new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(method.OverriddenMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics)); } else if (method.MethodKind == MethodKind.Destructor && this.SpecialType != SpecialType.System_Object) diff --git a/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs index b38e316698d8c..9d8a2338c78df 100644 --- a/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs @@ -891,9 +891,12 @@ private static int CustomModifierCount(Symbol member) } } - // CONSIDER: we could cache this on MethodSymbol + /// + /// Determine if this method requires a methodimpl table entry to inform the runtime of the override relationship. + /// internal static bool RequiresExplicitOverride(this MethodSymbol method) { + // CONSIDER: we could cache this on MethodSymbol if (method.IsOverride) { MethodSymbol csharpOverriddenMethod = method.OverriddenMethod; @@ -905,7 +908,8 @@ internal static bool RequiresExplicitOverride(this MethodSymbol method) // We can ignore interface implementation changes since the method is already metadata virtual (since override). // TODO: do we want to add more sophisticated handling for the case where there are multiple runtime-overridden methods? MethodSymbol runtimeOverriddenMethod = method.GetFirstRuntimeOverriddenMethodIgnoringNewSlot(ignoreInterfaceImplementationChanges: true); - return csharpOverriddenMethod != runtimeOverriddenMethod && + return runtimeOverriddenMethod is null || + csharpOverriddenMethod != runtimeOverriddenMethod && method.IsAccessor() != runtimeOverriddenMethod.IsAccessor(); } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index 4f47acb33abe6..c08e158446ba2 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -19,6 +19,15 @@ private static void VerifyOverride(CSharpCompilation comp, string methodName, st Assert.Equal(overridingMethodDisplay, method.ToTestDisplayString()); var overridden = method.GetOverriddenMember(); Assert.Equal(overriddenMethodDisplay, overridden.ToTestDisplayString()); + if (method is MethodSymbol overriderMethod && overridden is MethodSymbol overriddenMethod) + { + Assert.True(overriderMethod.IsOverride); + Assert.False(overriderMethod.IsVirtual); + Assert.True(overriderMethod.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true)); + var isCovariant = !overriderMethod.ReturnType.Equals(overriddenMethod.ReturnType, TypeCompareKind.AllIgnoreOptions); + Assert.Equal(isCovariant, overriderMethod.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true)); + Assert.Equal(isCovariant, overriderMethod.RequiresExplicitOverride()); // implies the presence of a methodimpl + } } private static void VerifyNoOverride(CSharpCompilation comp, string methodName) @@ -34,6 +43,33 @@ private static CSharpCompilation MetadataView(CSharpCompilation comp, params Met return CreateCompilation("", references: references); } + [Fact] + public void CovariantReturns_00() + { + var source = @" +public class Base +{ + public virtual string M() => null; +} +public class Derived : Base +{ + public override string M() => null; +} +"; + var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + ); + verify(comp); + comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + ); + verify(comp); + verify(MetadataView(comp)); + + static void verify(CSharpCompilation comp) + { + VerifyOverride(comp, "Derived.M", "System.String Derived.M()", "System.String Base.M()"); + } + } + [Fact] public void CovariantReturns_01() { @@ -1064,5 +1100,77 @@ static void verify(CSharpCompilation comp) VerifyOverride(comp, "Derived2.get_P", "System.String Derived2.P.get", "System.IComparable Derived.P.get"); } } + + [Fact] + public void CovariantReturns_17() + { + var source = @" +public class Base +{ + public virtual object M(string s) => null; + public virtual System.IComparable M(T s) => null; +} +public class Derived : Base +{ + public override string M(string s) => null; +} +"; + var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + // (9,28): error CS0462: The inherited members 'Base.M(string)' and 'Base.M(T)' have the same signature in type 'Derived', so they cannot be overridden + // public override string M(string s) => null; + Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("Base.M(string)", "Base.M(T)", "Derived").WithLocation(9, 28) + ); + verify(comp); + comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + // (9,28): error CS0462: The inherited members 'Base.M(string)' and 'Base.M(T)' have the same signature in type 'Derived', so they cannot be overridden + // public override string M(string s) => null; + Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("Base.M(string)", "Base.M(T)", "Derived").WithLocation(9, 28) + ); + verify(comp); + verify(MetadataView(comp)); + + static void verify(CSharpCompilation comp) + { + VerifyOverride(comp, "Derived.M", "System.String Derived.M(System.String s)", "System.Object Base.M(System.String s)"); + } + } + + [Fact] + public void CovariantReturns_18() + { + var source = @" +public class Base +{ + public virtual object M() => null; +} +public abstract class Derived : Base +{ + public abstract override System.IComparable M(); +} +public class Derived2 : Derived +{ + public override string M() => null; +} +"; + var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + // (8,49): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public abstract override System.IComparable M(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 49), + // (12,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public override string M() => null; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(12, 28) + ); + verify(comp); + comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + ); + verify(comp); + verify(MetadataView(comp)); + + static void verify(CSharpCompilation comp) + { + VerifyOverride(comp, "Derived.M", "System.IComparable Derived.M()", "System.Object Base.M()"); + VerifyOverride(comp, "Derived2.M", "System.String Derived2.M()", "System.IComparable Derived.M()"); + } + } } } From f4ceeee6bc61dd344a0b63c232d5532310929487 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Fri, 1 May 2020 11:56:23 -0700 Subject: [PATCH 3/6] Test the type returned from calling a covariantly overridden method. --- .../Symbol/Symbols/CovariantReturnTests.cs | 385 +++++++++++++++++- 1 file changed, 374 insertions(+), 11 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index c08e158446ba2..58d1938862a20 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; +using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; @@ -15,18 +18,55 @@ public class CovariantReturnTests : CSharpTestBase { private static void VerifyOverride(CSharpCompilation comp, string methodName, string overridingMethodDisplay, string overriddenMethodDisplay) { - var method = comp.GlobalNamespace.GetMember(methodName); - Assert.Equal(overridingMethodDisplay, method.ToTestDisplayString()); - var overridden = method.GetOverriddenMember(); - Assert.Equal(overriddenMethodDisplay, overridden.ToTestDisplayString()); - if (method is MethodSymbol overriderMethod && overridden is MethodSymbol overriddenMethod) + var member = comp.GlobalNamespace.GetMember(methodName); + Assert.Equal(overridingMethodDisplay, member.ToTestDisplayString()); + var overriddenMember = member.GetOverriddenMember(); + Assert.Equal(overriddenMethodDisplay, overriddenMember.ToTestDisplayString()); + if (member is MethodSymbol method && overriddenMember is MethodSymbol overriddenMethod) + { + Assert.True(method.IsOverride); + Assert.False(method.IsVirtual); + Assert.True(method.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true)); + var isCovariant = !method.ReturnType.Equals(overriddenMethod.ReturnType, TypeCompareKind.AllIgnoreOptions); + var checkMetadata = hasReturnConversion(method.ReturnType, overriddenMethod.ReturnType); + if (checkMetadata) + { + Assert.Equal(isCovariant, method.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true)); + Assert.Equal(isCovariant, method.RequiresExplicitOverride()); // implies the presence of a methodimpl + } + } + else if (member is PropertySymbol property && overriddenMember is PropertySymbol overriddenProperty) + { + var isCovariant = !property.Type.Equals(overriddenProperty.Type, TypeCompareKind.AllIgnoreOptions); + var checkMetadata = hasReturnConversion(property.Type, overriddenProperty.Type); + if (property.GetMethod is MethodSymbol getMethod && overriddenProperty.GetMethod is MethodSymbol overriddenGetMethod) + { + Assert.True(getMethod.GetOverriddenMember().Equals(overriddenGetMethod)); + if (checkMetadata) + { + Assert.Equal(isCovariant, getMethod.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true)); + Assert.Equal(isCovariant, getMethod.RequiresExplicitOverride()); // implies the presence of a methodimpl + } + } + if (property.SetMethod is MethodSymbol setMethod && overriddenProperty.SetMethod is MethodSymbol overriddenSetMethod) + { + Assert.False(setMethod.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true)); + Assert.False(setMethod.RequiresExplicitOverride()); + Assert.Equal(!isCovariant, overriddenSetMethod.Equals(setMethod.GetOverriddenMember(), TypeCompareKind.AllIgnoreOptions)); + } + } + else if (member is EventSymbol eventSymbol && overriddenMember is EventSymbol overriddenEvent) + { + } + else + { + Assert.True(false); + } + + bool hasReturnConversion(TypeSymbol fromType, TypeSymbol toType) { - Assert.True(overriderMethod.IsOverride); - Assert.False(overriderMethod.IsVirtual); - Assert.True(overriderMethod.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true)); - var isCovariant = !overriderMethod.ReturnType.Equals(overriddenMethod.ReturnType, TypeCompareKind.AllIgnoreOptions); - Assert.Equal(isCovariant, overriderMethod.IsMetadataNewSlot(ignoreInterfaceImplementationChanges: true)); - Assert.Equal(isCovariant, overriderMethod.RequiresExplicitOverride()); // implies the presence of a methodimpl + HashSet ignoredUseSiteDiagnostics = null; + return comp.Conversions.HasIdentityOrImplicitReferenceConversion(fromType, toType, ref ignoredUseSiteDiagnostics); } } @@ -37,6 +77,23 @@ private static void VerifyNoOverride(CSharpCompilation comp, string methodName) Assert.Null(overridden); } + /// + /// Verify that all assignments in the compilation's source have the same type and converted type. + /// + private static void VerifyAssignments(CSharpCompilation comp) + { + foreach (var tree in comp.SyntaxTrees) + { + var model = comp.GetSemanticModel(tree); + foreach (var assignment in tree.GetRoot().DescendantNodes().OfType()) + { + var right = assignment.Right; + var typeInfo = model.GetTypeInfo(right); + Assert.True(typeInfo.Type.GetSymbol().Equals(typeInfo.ConvertedType.GetSymbol(), TypeCompareKind.AllIgnoreOptions)); + } + } + } + private static CSharpCompilation MetadataView(CSharpCompilation comp, params MetadataReference[] references) { references = references.Append(comp.ToMetadataReference()); @@ -55,6 +112,14 @@ public class Derived : Base { public override string M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + string s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( ); @@ -67,6 +132,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M()", "System.String Base.M()"); + VerifyAssignments(comp); } } @@ -82,6 +148,14 @@ public class Derived : Base { public override string M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -97,6 +171,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M()", "System.Object Base.M()"); + VerifyAssignments(comp); } } @@ -112,6 +187,14 @@ public class Derived : Base { public override U M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -127,6 +210,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "U Derived.M()", "T Base.M()"); + VerifyAssignments(comp); } } @@ -142,6 +226,14 @@ public class Derived : Base where T : class where U : class, T { public override U M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -157,6 +249,7 @@ public class Derived : Base where T : class where U : class, T static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "U Derived.M()", "T Base.M()"); + VerifyAssignments(comp); } } @@ -173,6 +266,15 @@ public class Derived : Base where T : N { public override T M() => null; } +public class Q : N { } +public class Program +{ + void M(Base b, Derived d) + { + N s1 = b.M(); + Q s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -188,6 +290,7 @@ public class Derived : Base where T : N static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "T Derived.M()", "N Base.M()"); + VerifyAssignments(comp); } } @@ -203,6 +306,14 @@ public class Derived : Base { public override string M => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M; + string s2 = d.M; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -218,6 +329,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.Object Base.M { get; }"); + VerifyAssignments(comp); } } @@ -233,6 +345,14 @@ public class Derived : Base where T : class where U : class, T { public override U M => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M; + string s2 = d.M; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -248,6 +368,7 @@ public class Derived : Base where T : class where U : class, T static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "U Derived.M { get; }", "T Base.M { get; }"); + VerifyAssignments(comp); } } @@ -264,6 +385,15 @@ public class Derived : Base where T : N { public override T M => null; } +public class Q : N { } +public class Program +{ + void M(Base b, Derived d) + { + N s1 = b.M; + Q s2 = d.M; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -279,6 +409,7 @@ public class Derived : Base where T : N static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "T Derived.M { get; }", "N Base.M { get; }"); + VerifyAssignments(comp); } } @@ -294,6 +425,14 @@ public class Derived : Base { public override string this[int i] => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b[0]; + string s2 = d[0]; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -309,6 +448,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "System.String Derived.this[System.Int32 i] { get; }", "System.Object Base.this[System.Int32 i] { get; }"); + VerifyAssignments(comp); } } @@ -324,6 +464,14 @@ public class Derived : Base where T : class where U : class, T { public override U this[int i] => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b[0]; + string s2 = d[0]; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -339,6 +487,7 @@ public class Derived : Base where T : class where U : class, T static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "U Derived.this[System.Int32 i] { get; }", "T Base.this[System.Int32 i] { get; }"); + VerifyAssignments(comp); } } @@ -355,6 +504,15 @@ public class Derived : Base where T : N { public override T this[int i] => null; } +public class Q : N { } +public class Program +{ + void M(Base b, Derived d) + { + N s1 = b[0]; + Q s2 = d[0]; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -370,6 +528,7 @@ public class Derived : Base where T : N static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "T Derived.this[System.Int32 i] { get; }", "N Base.this[System.Int32 i] { get; }"); + VerifyAssignments(comp); } } @@ -421,6 +580,14 @@ public class Derived : Base { public override Func P { get; set; } } +public class Program +{ + void M(Base b, Derived d) + { + Func s1 = b.P; + Func s2 = d.P; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,34): error CS1715: 'Derived.P': type must be 'Func' to match overridden member 'Base.P' @@ -440,6 +607,7 @@ static void verify(CSharpCompilation comp) VerifyOverride(comp, "Derived.P", "System.Func Derived.P { get; set; }", "System.Func Base.P { get; set; }"); VerifyNoOverride(comp, "Derived.set_P"); VerifyOverride(comp, "Derived.get_P", "System.Func Derived.P.get", "System.Func Base.P.get"); + VerifyAssignments(comp); } } @@ -458,6 +626,14 @@ public class Derived : Base { public override string M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -473,6 +649,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M()", "System.Object Base.M()"); + VerifyAssignments(comp); } } @@ -491,6 +668,14 @@ public class Derived : Base { public override string M => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M; + string s2 = d.M; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -506,6 +691,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.Object Base.M { get; }"); + VerifyAssignments(comp); } } @@ -524,6 +710,14 @@ public class Derived : Base { public override string this[int i] => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b[0]; + string s2 = d[0]; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -539,6 +733,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "System.String Derived.this[System.Int32 i] { get; }", "System.Object Base.this[System.Int32 i] { get; }"); + VerifyAssignments(comp); } } @@ -554,6 +749,14 @@ public class Derived : Base { public override string M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + object s1 = b.M(); + string s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -569,6 +772,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M()", "System.Object Base.M()"); + VerifyAssignments(comp); } } @@ -584,6 +788,14 @@ public class Derived : Base { public override object M() => null; } +public class Program +{ + void M(Base b, Derived d) + { + string s1 = b.M(); + object s2 = d.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS0508: 'Derived.M()': return type must be 'string' to match overridden member 'Base.M()' @@ -601,6 +813,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.Object Derived.M()", "System.String Base.M()"); + VerifyAssignments(comp); } } @@ -628,6 +841,18 @@ public class Derived3 : Derived public new object M1 => null; public object M2 => null; } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2, Derived3 d3) + { + object x1 = b.M1; + object x2 = b.M2; + string x3 = d1.M1; + string x4 = d1.M2; + object x5 = d2.M1; + object x6 = d2.M2; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (10,19): warning CS0114: 'Derived.M2' hides inherited member 'Base.M2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. @@ -662,6 +887,7 @@ static void verify(CSharpCompilation comp) VerifyNoOverride(comp, "Derived2.M2"); VerifyNoOverride(comp, "Derived3.M1"); VerifyNoOverride(comp, "Derived3.M2"); + VerifyAssignments(comp); } } @@ -687,6 +913,21 @@ public class Derived2 : Derived public override object M2 => null; // 1 public override Base M3 => null; // 2 } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2) + { + object x1 = b.M1; + object x2 = b.M2; + object x3 = b.M3; + string x4 = d1.M1; + string x5 = d1.M2; + string x6 = d1.M3; + string x7 = d2.M1; + object x8 = d2.M2; + Base x9 = d2.M3; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (10,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -719,11 +960,20 @@ public class Derived2 : Derived static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "System.String Derived.M1 { get; }", "System.Object Base.M1 { get; }"); + VerifyOverride(comp, "Derived.get_M1", "System.String Derived.M1.get", "System.Object Base.M1.get"); VerifyOverride(comp, "Derived.M2", "System.String Derived.M2 { get; }", "System.Object Base.M2 { get; }"); + VerifyOverride(comp, "Derived.get_M2", "System.String Derived.M2.get", "System.Object Base.M2.get"); VerifyOverride(comp, "Derived.M3", "System.String Derived.M3 { get; }", "System.Object Base.M3 { get; }"); + VerifyOverride(comp, "Derived.get_M3", "System.String Derived.M3.get", "System.Object Base.M3.get"); + VerifyOverride(comp, "Derived2.M1", "System.String Derived2.M1 { get; }", "System.String Derived.M1 { get; }"); + VerifyOverride(comp, "Derived2.get_M1", "System.String Derived2.M1.get", "System.String Derived.M1.get"); VerifyOverride(comp, "Derived2.M2", "System.Object Derived2.M2 { get; }", "System.String Derived.M2 { get; }"); + VerifyOverride(comp, "Derived2.get_M2", "System.Object Derived2.M2.get", "System.String Derived.M2.get"); VerifyOverride(comp, "Derived2.M3", "Base Derived2.M3 { get; }", "System.String Derived.M3 { get; }"); + VerifyOverride(comp, "Derived2.get_M3", "Base Derived2.M3.get", "System.String Derived.M3.get"); + + VerifyAssignments(comp); } } @@ -743,6 +993,16 @@ public class Derived : Base } public interface IOut { } public interface IIn { } +public class Program +{ + void M(Base b, Derived d) + { + IIn x1 = b.M1; + IOut x2 = b.M2; + IIn x4 = d.M1; + IOut x5 = d.M2; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,33): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -762,6 +1022,7 @@ static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "IIn Derived.M1 { get; }", "IIn Base.M1 { get; }"); VerifyOverride(comp, "Derived.M2", "IOut Derived.M2 { get; }", "IOut Base.M2 { get; }"); + VerifyAssignments(comp); } } @@ -781,6 +1042,16 @@ public class Derived : Base } public interface IOut { } public interface IIn { } +public class Program +{ + void M(Base b, Derived d) + { + IIn x1 = b.M1; + IOut x2 = b.M2; + IIn x4 = d.M1; + IOut x5 = d.M2; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,33): error CS1715: 'Derived.M1': type must be 'IIn' to match overridden member 'Base.M1' @@ -805,6 +1076,7 @@ static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "IIn Derived.M1 { get; }", "IIn Base.M1 { get; }"); VerifyOverride(comp, "Derived.M2", "IOut Derived.M2 { get; }", "IOut Base.M2 { get; }"); + VerifyAssignments(comp); } } @@ -827,6 +1099,16 @@ public class B { public static implicit operator A(B b) => null; } +public class Program +{ + void M(Base b, Derived d) + { + int x1 = b.M1; + A x2 = b.M2; + short x4 = d.M1; + B x5 = d.M2; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,27): error CS1715: 'Derived.M1': type must be 'int' to match overridden member 'Base.M1' @@ -850,7 +1132,10 @@ public class B static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "System.Int16 Derived.M1 { get; }", "System.Int32 Base.M1 { get; }"); + VerifyOverride(comp, "Derived.get_M1", "System.Int16 Derived.M1.get", "System.Int32 Base.M1.get"); VerifyOverride(comp, "Derived.M2", "B Derived.M2 { get; }", "A Base.M2 { get; }"); + VerifyOverride(comp, "Derived.get_M2", "B Derived.M2.get", "A Base.M2.get"); + VerifyAssignments(comp); } } @@ -866,6 +1151,14 @@ public class Derived : Base { public override string M => null; } +public class Program +{ + void M(Base b, Derived d) + { + System.IComparable x1 = b.M; + string x2 = d.M; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -881,6 +1174,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.IComparable Base.M { get; }"); + VerifyAssignments(comp); } } @@ -903,6 +1197,16 @@ public class C : Base string Base.M1 => null; // 3 string Base.M2() => null; // 4 } +public class Program +{ + void M(Base b, Derived d, C c) + { + object x1 = b.M1; + object x2 = b.M2(); + object x3 = d.M1; + object x4 = d.M2(); + } +} "; // these are poor diagnostics; see https://github.com/dotnet/roslyn/issues/43719 var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( @@ -942,6 +1246,7 @@ static void verify(CSharpCompilation comp) VerifyNoOverride(comp, "Derived.Base.M2"); VerifyNoOverride(comp, "C.Base.M1"); VerifyNoOverride(comp, "C.Base.M2"); + VerifyAssignments(comp); } } @@ -957,6 +1262,14 @@ public class Derived : Base { public override string P { get => string.Empty; } } +public class Program +{ + void M(Base b, Derived d) + { + object x1 = b.P; + string x2 = d.P; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -973,6 +1286,7 @@ static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.P", "System.String Derived.P { get; }", "System.Object Base.P { get; set; }"); VerifyOverride(comp, "Derived.get_P", "System.String Derived.P.get", "System.Object Base.P.get"); + VerifyAssignments(comp); } } @@ -992,6 +1306,15 @@ public class Derived2 : Derived { public override string P { get => string.Empty; set { } } } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2) + { + object x1 = b.P; + string x2 = d1.P; + string x3 = d2.P; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -1016,6 +1339,7 @@ static void verify(CSharpCompilation comp) VerifyOverride(comp, "Derived2.P", "System.String Derived2.P { get; set; }", "System.String Derived.P { get; }"); VerifyOverride(comp, "Derived2.get_P", "System.String Derived2.P.get", "System.String Derived.P.get"); VerifyNoOverride(comp, "Derived2.set_P"); + VerifyAssignments(comp); } } @@ -1035,6 +1359,15 @@ public class Derived2 : Derived { public override string P { set { } } } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2) + { + object x1 = b.P; + string x2 = d1.P; + string x3 = d2.P; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -1058,6 +1391,7 @@ static void verify(CSharpCompilation comp) VerifyOverride(comp, "Derived.get_P", "System.String Derived.P.get", "System.Object Base.P.get"); VerifyOverride(comp, "Derived2.P", "System.String Derived2.P { set; }", "System.String Derived.P { get; }"); VerifyNoOverride(comp, "Derived2.set_P"); + VerifyAssignments(comp); } } @@ -1077,6 +1411,15 @@ public class Derived2 : Derived { public override string P { get => string.Empty; } } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2) + { + object x1 = b.P; + System.IComparable x2 = d1.P; + string x3 = d2.P; + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,40): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -1098,6 +1441,7 @@ static void verify(CSharpCompilation comp) VerifyOverride(comp, "Derived.get_P", "System.IComparable Derived.P.get", "System.Object Base.P.get"); VerifyOverride(comp, "Derived2.P", "System.String Derived2.P { get; }", "System.IComparable Derived.P { get; }"); VerifyOverride(comp, "Derived2.get_P", "System.String Derived2.P.get", "System.IComparable Derived.P.get"); + VerifyAssignments(comp); } } @@ -1114,6 +1458,14 @@ public class Derived : Base { public override string M(string s) => null; } +public class Program +{ + void M(Base b, Derived d, string s) + { + object x1 = b.M(s); + string x2 = d.M(s); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (9,28): error CS0462: The inherited members 'Base.M(string)' and 'Base.M(T)' have the same signature in type 'Derived', so they cannot be overridden @@ -1132,6 +1484,7 @@ public class Derived : Base static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M(System.String s)", "System.Object Base.M(System.String s)"); + VerifyAssignments(comp); } } @@ -1151,6 +1504,15 @@ public class Derived2 : Derived { public override string M() => null; } +public class Program +{ + void M(Base b, Derived d1, Derived2 d2) + { + object x1 = b.M(); + System.IComparable x2 = d1.M(); + string x3 = d2.M(); + } +} "; var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( // (8,49): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. @@ -1170,6 +1532,7 @@ static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.IComparable Derived.M()", "System.Object Base.M()"); VerifyOverride(comp, "Derived2.M", "System.String Derived2.M()", "System.IComparable Derived.M()"); + VerifyAssignments(comp); } } } From 045c671ef867334d47a92da6d1456c173ed81619 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Fri, 1 May 2020 14:31:04 -0700 Subject: [PATCH 4/6] Test VB consumption and overriding of covariant return methods declared in C#. --- .../Symbol/Symbols/CovariantReturnTests.cs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index 58d1938862a20..854094c20ed1a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.VisualBasic.Syntax; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -1535,5 +1536,75 @@ static void verify(CSharpCompilation comp) VerifyAssignments(comp); } } + + [Fact] + public void TestVBConsumption_01() + { + var source0 = @" +public class Base +{ + public virtual object M() => null; + public virtual object P => null; + public virtual object this[int i] => null; +} +public abstract class Derived : Base +{ + public override string M() => null; + public override string P => null; + public override string this[int i] => null; +} +"; + var csComp = CreateCompilation(source0, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + ); + csComp.VerifyDiagnostics(); + var csRef = csComp.EmitToImageReference(); + + var vbSource = @" +Public Class Derived2 : Inherits Derived + Public Overrides Function M() As String + Return Nothing + End Function + Public Overrides ReadOnly Property P As String + Get + Return Nothing + End Get + End Property + Public Overrides Default ReadOnly Property Item(i As Integer) As String + Get + Return Nothing + End Get + End Property + + Public Sub T(b as Base, d as Derived, d2 as Derived2) + Dim x1 As Object = b.M() + Dim x2 As Object = b.P + Dim x3 As Object = b(0) + Dim x4 As String = d.M() + Dim x5 As String = d.P + Dim x6 As String = d(0) + Dim x7 As String = d2.M() + Dim x8 As String = d2.P + Dim x9 As String = d2(0) + End Sub +End Class +"; + var vbComp = CreateVisualBasicCompilation(code: vbSource, referencedAssemblies: csComp.References.Append(csRef)); + vbComp.VerifyDiagnostics(); + var vbTree = vbComp.SyntaxTrees[0]; + var model = vbComp.GetSemanticModel(vbTree); + int count = 0; + foreach (var localDeclaration in vbTree.GetRoot().DescendantNodes().OfType()) + { + foreach (var declarator in localDeclaration.Declarators) + { + count++; + var initialValue = declarator.Initializer.Value; + var typeInfo = model.GetTypeInfo(initialValue); + Assert.True(typeInfo.Type.Equals(typeInfo.ConvertedType, TypeCompareKind.AllIgnoreOptions)); + } + } + + Assert.Equal(9, count); + } } } From 2052dcaa0f048ac58af327f849706d5860f7257c Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Mon, 4 May 2020 15:05:41 -0700 Subject: [PATCH 5/6] Make test helper methods for with and without covariant returns, so we have a place to put necessary support library declarations. --- .../Symbol/Symbols/CovariantReturnTests.cs | 146 ++++++++++-------- 1 file changed, 82 insertions(+), 64 deletions(-) diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index 854094c20ed1a..b55e4f6d77fae 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -8,7 +8,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; -using Microsoft.CodeAnalysis.VisualBasic.Syntax; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -58,6 +57,15 @@ private static void VerifyOverride(CSharpCompilation comp, string methodName, st } else if (member is EventSymbol eventSymbol && overriddenMember is EventSymbol overriddenEvent) { + var isCovariant = !eventSymbol.Type.Equals(overriddenEvent.Type, TypeCompareKind.AllIgnoreOptions); + if (eventSymbol.AddMethod is MethodSymbol addMethod && overriddenEvent.AddMethod is MethodSymbol overriddenAddMethod) + { + Assert.Equal(!isCovariant, overriddenAddMethod.Equals(addMethod.GetOverriddenMember(), TypeCompareKind.AllIgnoreOptions)); + } + if (eventSymbol.RemoveMethod is MethodSymbol removeMethod && overriddenEvent.RemoveMethod is MethodSymbol overriddenRemoveMethod) + { + Assert.Equal(!isCovariant, overriddenRemoveMethod.Equals(removeMethod.GetOverriddenMember(), TypeCompareKind.AllIgnoreOptions)); + } } else { @@ -95,6 +103,16 @@ private static void VerifyAssignments(CSharpCompilation comp) } } + private CSharpCompilation CreateCompilationWithCovariantReturns(string source, MetadataReference[] references = null, TargetFramework targetFramework = TargetFramework.Standard) + { + return CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: references, targetFramework: targetFramework); + } + + private CSharpCompilation CreateCompilationWithoutCovariantReturns(string source, MetadataReference[] references = null, TargetFramework targetFramework = TargetFramework.Standard) + { + return CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: references, targetFramework: targetFramework); + } + private static CSharpCompilation MetadataView(CSharpCompilation comp, params MetadataReference[] references) { references = references.Append(comp.ToMetadataReference()); @@ -122,10 +140,10 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -158,13 +176,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -197,13 +215,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override U M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -236,13 +254,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override U M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -277,13 +295,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override T M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(9, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -316,13 +334,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -355,13 +373,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override U M => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -396,13 +414,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override T M => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(9, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -435,13 +453,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string this[int i] => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "this").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -474,13 +492,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override U this[int i] => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "this").WithArguments("covariant returns").WithLocation(8, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -515,13 +533,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,23): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override T this[int i] => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "this").WithArguments("covariant returns").WithLocation(9, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -549,13 +567,13 @@ public class Derived : Base private void SuppressUnusedWarning() => E?.Invoke(); } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (10,40): error CS1715: 'Derived.E': type must be 'Func' to match overridden member 'Base.E' // public override event Func E; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "E").WithArguments("Derived.E", "Base.E", "System.Func").WithLocation(10, 40) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (10,40): error CS1715: 'Derived.E': type must be 'Func' to match overridden member 'Base.E' // public override event Func E; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "E").WithArguments("Derived.E", "Base.E", "System.Func").WithLocation(10, 40) @@ -590,13 +608,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,34): error CS1715: 'Derived.P': type must be 'Func' to match overridden member 'Base.P' // public override Func P { get; set; } Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "P").WithArguments("Derived.P", "Base.P", "System.Func").WithLocation(9, 34) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (9,34): error CS1715: 'Derived.P': type must be 'Func' to match overridden member 'Base.P' // public override Func P { get; set; } Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "P").WithArguments("Derived.P", "Base.P", "System.Func").WithLocation(9, 34) @@ -636,13 +654,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(4, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp, baseMetadata)); @@ -678,13 +696,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(4, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp, baseMetadata)); @@ -720,13 +738,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( // (4,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string this[int i] => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "this").WithArguments("covariant returns").WithLocation(4, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, references: new[] { baseMetadata }).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp, baseMetadata)); @@ -759,13 +777,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M() => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -798,13 +816,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS0508: 'Derived.M()': return type must be 'string' to match overridden member 'Base.M()' // public override object M() => null; Diagnostic(ErrorCode.ERR_CantChangeReturnTypeOnOverride, "M").WithArguments("Derived.M()", "Base.M()", "string").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS0508: 'Derived.M()': return type must be 'string' to match overridden member 'Base.M()' // public override object M() => null; Diagnostic(ErrorCode.ERR_CantChangeReturnTypeOnOverride, "M").WithArguments("Derived.M()", "Base.M()", "string").WithLocation(8, 28) @@ -855,7 +873,7 @@ void M(Base b, Derived d1, Derived2 d2, Derived3 d3) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (10,19): warning CS0114: 'Derived.M2' hides inherited member 'Base.M2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public string M2 => null; // A Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "M2").WithArguments("Derived.M2", "Base.M2").WithLocation(10, 19), @@ -867,7 +885,7 @@ void M(Base b, Derived d1, Derived2 d2, Derived3 d3) Diagnostic(ErrorCode.WRN_NewRequired, "M2").WithArguments("Derived3.M2", "Derived.M2").WithLocation(20, 19) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (10,19): warning CS0114: 'Derived.M2' hides inherited member 'Base.M2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public string M2 => null; // A Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "M2").WithArguments("Derived.M2", "Base.M2").WithLocation(10, 19), @@ -930,7 +948,7 @@ void M(Base b, Derived d1, Derived2 d2) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (10,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M1 => null; // A Diagnostic(ErrorCode.ERR_FeatureInPreview, "M1").WithArguments("covariant returns").WithLocation(10, 28), @@ -948,7 +966,7 @@ void M(Base b, Derived d1, Derived2 d2) Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M3").WithArguments("Derived2.M3", "Derived.M3", "string").WithLocation(18, 26) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (17,28): error CS1715: 'Derived2.M2': type must be 'string' to match overridden member 'Derived.M2' // public override object M2 => null; // 1 Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M2").WithArguments("Derived2.M2", "Derived.M2", "string").WithLocation(17, 28), @@ -1005,7 +1023,7 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,33): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override IIn M1 => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M1").WithArguments("covariant returns").WithLocation(9, 33), @@ -1014,7 +1032,7 @@ void M(Base b, Derived d) Diagnostic(ErrorCode.ERR_FeatureInPreview, "M2").WithArguments("covariant returns").WithLocation(10, 34) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -1054,7 +1072,7 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,33): error CS1715: 'Derived.M1': type must be 'IIn' to match overridden member 'Base.M1' // public override IIn M1 => null; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M1").WithArguments("Derived.M1", "Base.M1", "IIn").WithLocation(9, 33), @@ -1063,7 +1081,7 @@ void M(Base b, Derived d) Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M2").WithArguments("Derived.M2", "Base.M2", "IOut").WithLocation(10, 34) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (9,33): error CS1715: 'Derived.M1': type must be 'IIn' to match overridden member 'Base.M1' // public override IIn M1 => null; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M1").WithArguments("Derived.M1", "Base.M1", "IIn").WithLocation(9, 33), @@ -1111,7 +1129,7 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,27): error CS1715: 'Derived.M1': type must be 'int' to match overridden member 'Base.M1' // public override short M1 => 1; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M1").WithArguments("Derived.M1", "Base.M1", "int").WithLocation(9, 27), @@ -1120,7 +1138,7 @@ void M(Base b, Derived d) Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M2").WithArguments("Derived.M2", "Base.M2", "A").WithLocation(10, 23) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (9,27): error CS1715: 'Derived.M1': type must be 'int' to match overridden member 'Base.M1' // public override short M1 => 1; Diagnostic(ErrorCode.ERR_CantChangeTypeOnOverride, "M1").WithArguments("Derived.M1", "Base.M1", "int").WithLocation(9, 27), @@ -1161,13 +1179,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string M => null; Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -1210,7 +1228,7 @@ void M(Base b, Derived d, C c) } "; // these are poor diagnostics; see https://github.com/dotnet/roslyn/issues/43719 - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( // (9,17): error CS0539: 'Derived.M1' in explicit interface declaration is not found among members of the interface that can be implemented // string Base.M1 => null; // 1 Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Derived.M1").WithLocation(9, 17), @@ -1225,7 +1243,7 @@ void M(Base b, Derived d, C c) Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M2").WithArguments("C.M2()").WithLocation(15, 17) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source, targetFramework: TargetFramework.NetStandardLatest).VerifyDiagnostics( // (9,17): error CS0539: 'Derived.M1' in explicit interface declaration is not found among members of the interface that can be implemented // string Base.M1 => null; // 1 Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Derived.M1").WithLocation(9, 17), @@ -1272,13 +1290,13 @@ void M(Base b, Derived d) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string P { get; } Diagnostic(ErrorCode.ERR_FeatureInPreview, "P").WithArguments("covariant returns").WithLocation(8, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -1317,7 +1335,7 @@ void M(Base b, Derived d1, Derived2 d2) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string P { get => string.Empty; } Diagnostic(ErrorCode.ERR_FeatureInPreview, "P").WithArguments("covariant returns").WithLocation(8, 28), @@ -1326,7 +1344,7 @@ void M(Base b, Derived d1, Derived2 d2) Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived2.P.set", "Derived.P").WithLocation(12, 53) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (12,53): error CS0546: 'Derived2.P.set': cannot override because 'Derived.P' does not have an overridable set accessor // public override string P { get => string.Empty; set { } } Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived2.P.set", "Derived.P").WithLocation(12, 53) @@ -1370,7 +1388,7 @@ void M(Base b, Derived d1, Derived2 d2) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,28): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override string P { get => string.Empty; } Diagnostic(ErrorCode.ERR_FeatureInPreview, "P").WithArguments("covariant returns").WithLocation(8, 28), @@ -1379,7 +1397,7 @@ void M(Base b, Derived d1, Derived2 d2) Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived2.P.set", "Derived.P").WithLocation(12, 32) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (12,32): error CS0546: 'Derived2.P.set': cannot override because 'Derived.P' does not have an overridable set accessor // public override string P { set { } } Diagnostic(ErrorCode.ERR_NoSetToOverride, "set").WithArguments("Derived2.P.set", "Derived.P").WithLocation(12, 32) @@ -1422,7 +1440,7 @@ void M(Base b, Derived d1, Derived2 d2) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,40): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public override System.IComparable P { get => string.Empty; } Diagnostic(ErrorCode.ERR_FeatureInPreview, "P").WithArguments("covariant returns").WithLocation(8, 40), @@ -1431,7 +1449,7 @@ void M(Base b, Derived d1, Derived2 d2) Diagnostic(ErrorCode.ERR_FeatureInPreview, "P").WithArguments("covariant returns").WithLocation(12, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -1468,13 +1486,13 @@ void M(Base b, Derived d, string s) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (9,28): error CS0462: The inherited members 'Base.M(string)' and 'Base.M(T)' have the same signature in type 'Derived', so they cannot be overridden // public override string M(string s) => null; Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("Base.M(string)", "Base.M(T)", "Derived").WithLocation(9, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( // (9,28): error CS0462: The inherited members 'Base.M(string)' and 'Base.M(T)' have the same signature in type 'Derived', so they cannot be overridden // public override string M(string s) => null; Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("Base.M(string)", "Base.M(T)", "Derived").WithLocation(9, 28) @@ -1515,7 +1533,7 @@ void M(Base b, Derived d1, Derived2 d2) } } "; - var comp = CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns).VerifyDiagnostics( + var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( // (8,49): error CS8652: The feature 'covariant returns' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public abstract override System.IComparable M(); Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(8, 49), @@ -1524,7 +1542,7 @@ void M(Base b, Derived d1, Derived2 d2) Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("covariant returns").WithLocation(12, 28) ); verify(comp); - comp = CreateCompilation(source, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); verify(MetadataView(comp)); @@ -1554,7 +1572,7 @@ public abstract class Derived : Base public override string this[int i] => null; } "; - var csComp = CreateCompilation(source0, parseOptions: TestOptions.WithCovariantReturns).VerifyDiagnostics( + var csComp = CreateCompilationWithCovariantReturns(source0).VerifyDiagnostics( ); csComp.VerifyDiagnostics(); var csRef = csComp.EmitToImageReference(); From 3ffbe679fd9830cc0e07f198ce77dac1bc5ef1ec Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Tue, 5 May 2020 12:55:44 -0700 Subject: [PATCH 6/6] Read covariant return override information [methodimpl] from metadata. --- .../Symbols/Metadata/PE/PEMethodSymbol.cs | 46 ++++++++++++++---- .../Symbols/Metadata/PE/PEPropertySymbol.cs | 15 ++++++ .../OverriddenOrHiddenMembersHelpers.cs | 38 ++++++++++++--- .../Symbol/Symbols/CovariantReturnTests.cs | 47 +++++++++++++++++-- 4 files changed, 127 insertions(+), 19 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 0f11239549897..e6cf8e0590d6f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -1166,13 +1166,7 @@ public override ImmutableArray ExplicitInterfaceImplementations return explicitInterfaceImplementations; } - var moduleSymbol = _containingType.ContainingPEModule; - - // Context: we need the containing type of this method as context so that we can substitute appropriately into - // any generic interfaces that we might be explicitly implementing. There is no reason to pass in the method - // context, however, because any method type parameters will belong to the implemented (i.e. interface) method, - // which we do not yet know. - var explicitlyOverriddenMethods = new MetadataDecoder(moduleSymbol, _containingType).GetExplicitlyOverriddenMethods(_containingType.Handle, _handle, this.ContainingType); + var explicitlyOverriddenMethods = ExplicitlyOverriddenMethods(); //avoid allocating a builder in the common case var anyToRemove = false; @@ -1183,9 +1177,9 @@ public override ImmutableArray ExplicitInterfaceImplementations { anyToRemove = true; sawObjectFinalize = - (method.ContainingType.SpecialType == SpecialType.System_Object && - method.Name == WellKnownMemberNames.DestructorName && // Cheaper than MethodKind. - method.MethodKind == MethodKind.Destructor); + (method.ContainingType.SpecialType == SpecialType.System_Object && + method.Name == WellKnownMemberNames.DestructorName && // Cheaper than MethodKind. + method.MethodKind == MethodKind.Destructor); } if (anyToRemove && sawObjectFinalize) @@ -1221,6 +1215,38 @@ public override ImmutableArray ExplicitInterfaceImplementations } } + private ImmutableArray ExplicitlyOverriddenMethods() + { + var moduleSymbol = _containingType.ContainingPEModule; + + // Context: we need the containing type of this method as context so that we can substitute appropriately into + // any generic interfaces that we might be explicitly implementing. There is no reason to pass in the method + // context, however, because any method type parameters will belong to the implemented (i.e. interface) method, + // which we do not yet know. + return new MetadataDecoder(moduleSymbol, _containingType).GetExplicitlyOverriddenMethods(_containingType.Handle, _handle, this.ContainingType); + } + + internal MethodSymbol ExplicitlyOverriddenClassMethod + { + get + { + if (IsExplicitClassOverride) + { + foreach (MethodSymbol method in ExplicitlyOverriddenMethods()) + { + if (method.ContainingType.IsClassType()) + { + return method; + } + } + + throw ExceptionUtilities.Unreachable; + } + + return null; + } + } + internal override bool IsDeclaredReadOnly { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs index c288ac9954821..b5e2af54aca7d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEPropertySymbol.cs @@ -536,6 +536,21 @@ public override ImmutableArray DeclaringSyntaxReferences } } + internal PropertySymbol ExplicitlyOverriddenClassProperty + { + get + { + // A covariant return readonly property override is indicated in metadata by + // a get accessor with an explicit override (methodimpl). + if (GetMethod is PEMethodSymbol { ExplicitlyOverriddenClassMethod: { AssociatedSymbol: PropertySymbol overriddenProperty } }) + { + return overriddenProperty; + } + + return null; + } + } + public override ImmutableArray GetAttributes() { if (_lazyCustomAttributes.IsDefault) diff --git a/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs index 9d8a2338c78df..123e75e3bb9f7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/OverriddenOrHiddenMembersHelpers.cs @@ -6,8 +6,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Linq; -using Microsoft.CodeAnalysis.Collections; -using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; @@ -132,6 +131,14 @@ private static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembersWork Symbol bestMatch = null; ArrayBuilder hiddenBuilder = null; + // If the metadata indicates a specific override, use that. + Symbol explicitOverride = member switch + { + PEMethodSymbol method => method.ExplicitlyOverriddenClassMethod, + PEPropertySymbol property => property.ExplicitlyOverriddenClassProperty, + _ => null + }; + for (NamedTypeSymbol currType = containingType.BaseTypeNoUseSiteDiagnostics; (object)currType != null && (object)bestMatch == null && hiddenBuilder == null; currType = currType.BaseTypeNoUseSiteDiagnostics) @@ -141,6 +148,7 @@ private static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembersWork member, memberIsFromSomeCompilation, containingType, + explicitOverride, currType, out bestMatch, out unused, @@ -238,9 +246,7 @@ private static OverriddenOrHiddenMembersResult MakePropertyAccessorOverriddenOrH ImmutableArray overriddenAccessors = ImmutableArray.Empty; ImmutableArray runtimeOverriddenAccessors = ImmutableArray.Empty; if ((object)overriddenAccessor != null && IsOverriddenSymbolAccessible(overriddenAccessor, accessor.ContainingType) && - (accessorIsFromSomeCompilation - ? MemberSignatureComparer.CSharpAccessorOverrideComparer.Equals(accessor, overriddenAccessor) //NB: custom comparer - : MemberSignatureComparer.RuntimeSignatureComparer.Equals(accessor, overriddenAccessor))) + isAccessorOverride(accessor, overriddenAccessor)) { FindRelatedMembers( accessor.IsOverride, accessorIsFromSomeCompilation, accessor.Kind, overriddenAccessor, out overriddenAccessors, out runtimeOverriddenAccessors, ref hiddenBuilder); @@ -248,6 +254,22 @@ private static OverriddenOrHiddenMembersResult MakePropertyAccessorOverriddenOrH ImmutableArray hiddenMembers = hiddenBuilder == null ? ImmutableArray.Empty : hiddenBuilder.ToImmutableAndFree(); return OverriddenOrHiddenMembersResult.Create(overriddenAccessors, hiddenMembers, runtimeOverriddenAccessors); + + bool isAccessorOverride(MethodSymbol accessor, MethodSymbol overriddenAccessor) + { + if (accessorIsFromSomeCompilation) + { + return MemberSignatureComparer.CSharpAccessorOverrideComparer.Equals(accessor, overriddenAccessor); //NB: custom comparer + } + + if (accessor is PEMethodSymbol { ExplicitlyOverriddenClassMethod: MethodSymbol peOverriddenAccessor } && + overriddenAccessor.Equals(peOverriddenAccessor, TypeCompareKind.AllIgnoreOptions)) + { + return true; + } + + return MemberSignatureComparer.RuntimeSignatureComparer.Equals(accessor, overriddenAccessor); + } } /// @@ -377,6 +399,7 @@ internal static OverriddenOrHiddenMembersResult MakeInterfaceOverriddenOrHiddenM member, memberIsFromSomeCompilation, containingType, + explicitOverride: null, currType, out currTypeBestMatch, out currTypeHasSameKindNonMatch, @@ -460,6 +483,7 @@ internal static OverriddenOrHiddenMembersResult MakeInterfaceOverriddenOrHiddenM /// Member that is hiding or overriding. /// True if member is from the current compilation. /// The type that contains member (member.ContainingType). + /// An explicitly overridden class member. /// The type to search. /// /// A member with the same signature if currTypeHasExactMatch is true, @@ -477,6 +501,7 @@ private static void FindOverriddenOrHiddenMembersInType( Symbol member, bool memberIsFromSomeCompilation, NamedTypeSymbol memberContainingType, + Symbol explicitOverride, NamedTypeSymbol currType, out Symbol currTypeBestMatch, out bool currTypeHasSameKindNonMatch, @@ -540,7 +565,8 @@ private static void FindOverriddenOrHiddenMembersInType( break; default: - if (exactMatchComparer.Equals(member, otherMember)) + if (otherMember.Equals(explicitOverride, TypeCompareKind.AllIgnoreOptions) || + exactMatchComparer.Equals(member, otherMember)) { currTypeHasExactMatch = true; currTypeBestMatch = otherMember; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs index b55e4f6d77fae..8761dff54b02c 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CovariantReturnTests.cs @@ -21,7 +21,7 @@ private static void VerifyOverride(CSharpCompilation comp, string methodName, st var member = comp.GlobalNamespace.GetMember(methodName); Assert.Equal(overridingMethodDisplay, member.ToTestDisplayString()); var overriddenMember = member.GetOverriddenMember(); - Assert.Equal(overriddenMethodDisplay, overriddenMember.ToTestDisplayString()); + Assert.Equal(overriddenMethodDisplay, overriddenMember?.ToTestDisplayString()); if (member is MethodSymbol method && overriddenMember is MethodSymbol overriddenMethod) { Assert.True(method.IsOverride); @@ -113,12 +113,18 @@ private CSharpCompilation CreateCompilationWithoutCovariantReturns(string source return CreateCompilation(source, parseOptions: TestOptions.WithoutCovariantReturns, references: references, targetFramework: targetFramework); } - private static CSharpCompilation MetadataView(CSharpCompilation comp, params MetadataReference[] references) + private static CSharpCompilation CompilationReferenceView(CSharpCompilation comp, params MetadataReference[] references) { references = references.Append(comp.ToMetadataReference()); return CreateCompilation("", references: references); } + private static CSharpCompilation MetadataView(CSharpCompilation comp, params MetadataReference[] references) + { + references = references.Append(comp.EmitToImageReference()); + return CreateCompilation("", references: references); + } + [Fact] public void CovariantReturns_00() { @@ -143,9 +149,13 @@ void M(Base b, Derived d) var comp = CreateCompilationWithoutCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); + verify(MetadataView(comp)); + comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -185,6 +195,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -224,6 +235,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -263,6 +275,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -304,6 +317,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -343,11 +357,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.Object Base.M { get; }"); + VerifyOverride(comp, "Derived.get_M", "System.String Derived.M.get", "System.Object Base.M.get"); VerifyAssignments(comp); } } @@ -382,11 +398,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "U Derived.M { get; }", "T Base.M { get; }"); + VerifyOverride(comp, "Derived.get_M", "U Derived.M.get", "T Base.M.get"); VerifyAssignments(comp); } } @@ -423,11 +441,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "T Derived.M { get; }", "N Base.M { get; }"); + VerifyOverride(comp, "Derived.get_M", "T Derived.M.get", "N Base.M.get"); VerifyAssignments(comp); } } @@ -462,11 +482,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "System.String Derived.this[System.Int32 i] { get; }", "System.Object Base.this[System.Int32 i] { get; }"); + VerifyOverride(comp, "Derived.get_Item", "System.String Derived.this[System.Int32 i].get", "System.Object Base.this[System.Int32 i].get"); VerifyAssignments(comp); } } @@ -501,11 +523,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "U Derived.this[System.Int32 i] { get; }", "T Base.this[System.Int32 i] { get; }"); + VerifyOverride(comp, "Derived.get_Item", "U Derived.this[System.Int32 i].get", "T Base.this[System.Int32 i].get"); VerifyAssignments(comp); } } @@ -542,11 +566,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "T Derived.this[System.Int32 i] { get; }", "N Base.this[System.Int32 i] { get; }"); + VerifyOverride(comp, "Derived.get_Item", "T Derived.this[System.Int32 i].get", "N Base.this[System.Int32 i].get"); VerifyAssignments(comp); } } @@ -663,6 +689,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp, baseMetadata)); verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) @@ -705,11 +732,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp, baseMetadata)); verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.Object Base.M { get; }"); + VerifyOverride(comp, "Derived.get_M", "System.String Derived.M.get", "System.Object Base.M.get"); VerifyAssignments(comp); } } @@ -747,11 +776,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source, references: new[] { baseMetadata }).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp, baseMetadata)); verify(MetadataView(comp, baseMetadata)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.this[]", "System.String Derived.this[System.Int32 i] { get; }", "System.Object Base.this[System.Int32 i] { get; }"); + VerifyOverride(comp, "Derived.get_Item", "System.String Derived.this[System.Int32 i].get", "System.Object Base.this[System.Int32 i].get"); VerifyAssignments(comp); } } @@ -786,6 +817,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -1035,12 +1067,15 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "IIn Derived.M1 { get; }", "IIn Base.M1 { get; }"); + VerifyOverride(comp, "Derived.get_M1", "IIn Derived.M1.get", "IIn Base.M1.get"); VerifyOverride(comp, "Derived.M2", "IOut Derived.M2 { get; }", "IOut Base.M2 { get; }"); + VerifyOverride(comp, "Derived.get_M2", "IOut Derived.M2.get", "IOut Base.M2.get"); VerifyAssignments(comp); } } @@ -1094,7 +1129,9 @@ void M(Base b, Derived d) static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M1", "IIn Derived.M1 { get; }", "IIn Base.M1 { get; }"); + VerifyOverride(comp, "Derived.get_M1", "IIn Derived.M1.get", "IIn Base.M1.get"); VerifyOverride(comp, "Derived.M2", "IOut Derived.M2 { get; }", "IOut Base.M2 { get; }"); + VerifyOverride(comp, "Derived.get_M2", "IOut Derived.M2.get", "IOut Base.M2.get"); VerifyAssignments(comp); } } @@ -1188,11 +1225,13 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { VerifyOverride(comp, "Derived.M", "System.String Derived.M { get; }", "System.IComparable Base.M { get; }"); + VerifyOverride(comp, "Derived.get_M", "System.String Derived.M.get", "System.IComparable Base.M.get"); VerifyAssignments(comp); } } @@ -1299,6 +1338,7 @@ void M(Base b, Derived d) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -1452,6 +1492,7 @@ void M(Base b, Derived d1, Derived2 d2) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp) @@ -1498,7 +1539,6 @@ void M(Base b, Derived d, string s) Diagnostic(ErrorCode.ERR_AmbigOverride, "M").WithArguments("Base.M(string)", "Base.M(T)", "Derived").WithLocation(9, 28) ); verify(comp); - verify(MetadataView(comp)); static void verify(CSharpCompilation comp) { @@ -1545,6 +1585,7 @@ void M(Base b, Derived d1, Derived2 d2) comp = CreateCompilationWithCovariantReturns(source).VerifyDiagnostics( ); verify(comp); + verify(CompilationReferenceView(comp)); verify(MetadataView(comp)); static void verify(CSharpCompilation comp)