From 23f3b94865d1adddb21ca0c813cc839b42984685 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Thu, 13 May 2021 23:34:23 +0200 Subject: [PATCH 01/16] Use covariant return for synthesized record clone --- .../Symbols/Synthesized/Records/SynthesizedRecordClone.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs index 35dcd9f5949fa..fee09b4ce5db3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs @@ -97,8 +97,8 @@ static bool modifiersAreValid(DeclarationModifiers modifiers) protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { - return (ReturnType: VirtualCloneInBase() is { } baseClone ? - baseClone.ReturnTypeWithAnnotations : // Use covariant returns when available + return (ReturnType: VirtualCloneInBase() is { } baseClone && !ContainingAssembly.RuntimeSupportsCovariantReturnsOfClasses ? + baseClone.ReturnTypeWithAnnotations : TypeWithAnnotations.Create(isNullableEnabled: true, ContainingType), Parameters: ImmutableArray.Empty, IsVararg: false, From c21e7cfe0922229034c02ce9f92f69d82db6880d Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 08:49:49 +0200 Subject: [PATCH 02/16] Update tests --- .../Test/Semantic/Semantics/RecordTests.cs | 297 ++++++++++++++++-- 1 file changed, 274 insertions(+), 23 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 9d48894caf363..1ef6d402bdae8 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -11,8 +11,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FlowAnalysis; -using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; @@ -26,6 +24,10 @@ private static CSharpCompilation CreateCompilation(CSharpTestSource source) => CSharpTestBase.CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview); + private static CSharpCompilation CreateCompilationWithCovariantReturns(CSharpTestSource source) + => CSharpTestBase.CreateCompilation(new[] { source }, + parseOptions: TestOptions.RegularPreview, targetFramework: TargetFramework.NetCoreApp); + private CompilationVerifier CompileAndVerify( CSharpTestSource src, string? expectedOutput = null, @@ -374,7 +376,6 @@ record R3([System.Diagnostics.CodeAnalysis.NotNull] R3 x); // record R3([System.Diagnostics.CodeAnalysis.NotNull] R3 x); Diagnostic(ErrorCode.ERR_RecordAmbigCtor, "R3").WithLocation(7, 8) ); - var r = comp.GlobalNamespace.GetTypeMember("R"); Assert.Equal(new[] { "R..ctor(R x)", "R..ctor(R original)" }, r.GetMembers(".ctor").ToTestDisplayStrings()); } @@ -10807,8 +10808,10 @@ record C(object P1, object P2) : B AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers); } - [Fact] - public void Inheritance_24() + [Theory] + [InlineData(TargetFramework.NetCoreApp)] + [InlineData(TargetFramework.Standard)] + public void Inheritance_24(TargetFramework targetFramework) { var source = @"record A @@ -10824,12 +10827,28 @@ record C(object P) public object get_P() => null; public object set_Q() => null; }"; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, targetFramework: targetFramework); comp.VerifyDiagnostics( // (9,17): error CS0082: Type 'C' already reserves a member called 'get_P' with the same parameter types // record C(object P) Diagnostic(ErrorCode.ERR_MemberReserved, "P").WithArguments("get_P", "C").WithLocation(9, 17)); + string expectedClone; + if (targetFramework == TargetFramework.Standard) + { + Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else if (targetFramework == TargetFramework.NetCoreApp) + { + Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else + { + throw ExceptionUtilities.Unreachable; + } + var expectedMembers = new[] { "B..ctor(System.Object P, System.Object Q)", @@ -10851,7 +10870,7 @@ record C(object P) "System.Boolean B.Equals(System.Object? obj)", "System.Boolean B.Equals(A? other)", "System.Boolean B.Equals(B? other)", - "A B." + WellKnownMemberNames.CloneMethodName + "()", + expectedClone, "B..ctor(B original)", "void B.Deconstruct(out System.Object P, out System.Object Q)" }; @@ -12688,15 +12707,18 @@ .maxstack 8 } [Theory, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")] - [InlineData(false)] - [InlineData(true)] - public void CopyCtor(bool useCompilationReference) + [InlineData(false, TargetFramework.Standard)] + [InlineData(false, TargetFramework.NetCoreApp)] + [InlineData(true, TargetFramework.Standard)] + [InlineData(true, TargetFramework.NetCoreApp)] + public void CopyCtor(bool useCompilationReference, TargetFramework targetFramework) { var sourceA = @"public record B(object N1, object N2) { }"; - var compA = CreateCompilation(sourceA); + CSharpTestSource testSourceA = targetFramework == TargetFramework.Standard ? new[] { sourceA, IsExternalInitTypeDefinition } : sourceA; + var compA = CreateCompilation(testSourceA, targetFramework: targetFramework); var verifierA = CompileAndVerify(compA, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); verifierA.VerifyIL("B..ctor(B)", @" @@ -12735,7 +12757,8 @@ static void Main() System.Console.Write((c3.P1, c3.P2, c3.N1, c3.N2)); } }"; - var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe); + CSharpTestSource testSourceB = targetFramework == TargetFramework.Standard ? new[] { sourceB, IsExternalInitTypeDefinition } : sourceB; + var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: targetFramework); var verifierB = CompileAndVerify(compB, expectedOutput: "(1, 2, 3, 4) (1, 2, 3, 4) (10, 2, 30, 4)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); // call base copy constructor B..ctor(B) @@ -15888,8 +15911,10 @@ record B(int X, int Y) : A AssertEx.Equal(expectedMembers, actualMembers); } - [Fact] - public void Overrides_02() + [Theory] + [InlineData(TargetFramework.NetCoreApp)] + [InlineData(TargetFramework.Standard)] + public void Overrides_02(TargetFramework targetFramework) { var source = @"abstract record A @@ -15901,7 +15926,7 @@ public void Overrides_02() record B(int X, int Y) : A { }"; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, targetFramework: targetFramework); comp.VerifyDiagnostics( // (3,35): error CS0111: Type 'A' already defines a member called 'Equals' with the same parameter types // public abstract override bool Equals(object other); @@ -15911,6 +15936,22 @@ record B(int X, int Y) : A Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.Equals(object)").WithLocation(7, 8) ); + string expectedClone; + if (targetFramework == TargetFramework.Standard) + { + Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else if (targetFramework == TargetFramework.NetCoreApp) + { + Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else + { + throw ExceptionUtilities.Unreachable; + } + var actualMembers = comp.GetMember("B").GetMembers().ToTestDisplayStrings(); var expectedMembers = new[] { @@ -15933,7 +15974,7 @@ record B(int X, int Y) : A "System.Boolean B.Equals(System.Object? obj)", "System.Boolean B.Equals(A? other)", "System.Boolean B.Equals(B? other)", - "A B." + WellKnownMemberNames.CloneMethodName + "()", + expectedClone, "B..ctor(B original)", "void B.Deconstruct(out System.Int32 X, out System.Int32 Y)" }; @@ -21080,6 +21121,175 @@ .locals init (C V_0, //c }"); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WithExprReference_WithCovariantReturns(bool emitRef) + { + var src = @" +public record C +{ + public int X { get; init; } +} +public record D(int Y) : C;"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp); + comp.VerifyDiagnostics(); + + var src2 = @" +using System; +class E +{ + public static void Main() + { + var c = new C() { X = 1 }; + var c2 = c with { X = 2 }; + Console.WriteLine(c.X); + Console.WriteLine(c2.X); + + var d = new D(2) { X = 1 }; + var d2 = d with { X = 2, Y = 3 }; + Console.WriteLine(d.X + "" "" + d.Y); + Console.WriteLine(d2.X + "" "" + d2.Y); + + C c3 = d; + C c4 = d2; + c3 = c3 with { X = 3 }; + c4 = c4 with { X = 4 }; + + d = (D)c3; + d2 = (D)c4; + Console.WriteLine(d.X + "" "" + d.Y); + Console.WriteLine(d2.X + "" "" + d2.Y); + } +}"; + var verifier = CompileAndVerify(src2, + references: new[] { emitRef ? comp.EmitToImageReference() : comp.ToMetadataReference() }, + expectedOutput: @" +1 +2 +1 2 +2 3 +3 2 +4 3", targetFramework: TargetFramework.NetCoreApp).VerifyDiagnostics(); + + verifier.VerifyIL("E.Main", @" +{ + // Code size 313 (0x139) + .maxstack 3 + .locals init (C V_0, //c + D V_1, //d + D V_2, //d2 + C V_3, //c3 + C V_4, //c4 + int V_5) + IL_0000: newobj ""C..ctor()"" + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: callvirt ""void C.X.init"" + IL_000c: stloc.0 + IL_000d: ldloc.0 + IL_000e: callvirt ""C C.$()"" + IL_0013: dup + IL_0014: ldc.i4.2 + IL_0015: callvirt ""void C.X.init"" + IL_001a: ldloc.0 + IL_001b: callvirt ""int C.X.get"" + IL_0020: call ""void System.Console.WriteLine(int)"" + IL_0025: callvirt ""int C.X.get"" + IL_002a: call ""void System.Console.WriteLine(int)"" + IL_002f: ldc.i4.2 + IL_0030: newobj ""D..ctor(int)"" + IL_0035: dup + IL_0036: ldc.i4.1 + IL_0037: callvirt ""void C.X.init"" + IL_003c: stloc.1 + IL_003d: ldloc.1 + IL_003e: callvirt ""D D.$()"" + IL_0043: dup + IL_0044: ldc.i4.2 + IL_0045: callvirt ""void C.X.init"" + IL_004a: dup + IL_004b: ldc.i4.3 + IL_004c: callvirt ""void D.Y.init"" + IL_0051: stloc.2 + IL_0052: ldloc.1 + IL_0053: callvirt ""int C.X.get"" + IL_0058: stloc.s V_5 + IL_005a: ldloca.s V_5 + IL_005c: call ""string int.ToString()"" + IL_0061: ldstr "" "" + IL_0066: ldloc.1 + IL_0067: callvirt ""int D.Y.get"" + IL_006c: stloc.s V_5 + IL_006e: ldloca.s V_5 + IL_0070: call ""string int.ToString()"" + IL_0075: call ""string string.Concat(string, string, string)"" + IL_007a: call ""void System.Console.WriteLine(string)"" + IL_007f: ldloc.2 + IL_0080: callvirt ""int C.X.get"" + IL_0085: stloc.s V_5 + IL_0087: ldloca.s V_5 + IL_0089: call ""string int.ToString()"" + IL_008e: ldstr "" "" + IL_0093: ldloc.2 + IL_0094: callvirt ""int D.Y.get"" + IL_0099: stloc.s V_5 + IL_009b: ldloca.s V_5 + IL_009d: call ""string int.ToString()"" + IL_00a2: call ""string string.Concat(string, string, string)"" + IL_00a7: call ""void System.Console.WriteLine(string)"" + IL_00ac: ldloc.1 + IL_00ad: stloc.3 + IL_00ae: ldloc.2 + IL_00af: stloc.s V_4 + IL_00b1: ldloc.3 + IL_00b2: callvirt ""C C.$()"" + IL_00b7: dup + IL_00b8: ldc.i4.3 + IL_00b9: callvirt ""void C.X.init"" + IL_00be: stloc.3 + IL_00bf: ldloc.s V_4 + IL_00c1: callvirt ""C C.$()"" + IL_00c6: dup + IL_00c7: ldc.i4.4 + IL_00c8: callvirt ""void C.X.init"" + IL_00cd: stloc.s V_4 + IL_00cf: ldloc.3 + IL_00d0: castclass ""D"" + IL_00d5: stloc.1 + IL_00d6: ldloc.s V_4 + IL_00d8: castclass ""D"" + IL_00dd: stloc.2 + IL_00de: ldloc.1 + IL_00df: callvirt ""int C.X.get"" + IL_00e4: stloc.s V_5 + IL_00e6: ldloca.s V_5 + IL_00e8: call ""string int.ToString()"" + IL_00ed: ldstr "" "" + IL_00f2: ldloc.1 + IL_00f3: callvirt ""int D.Y.get"" + IL_00f8: stloc.s V_5 + IL_00fa: ldloca.s V_5 + IL_00fc: call ""string int.ToString()"" + IL_0101: call ""string string.Concat(string, string, string)"" + IL_0106: call ""void System.Console.WriteLine(string)"" + IL_010b: ldloc.2 + IL_010c: callvirt ""int C.X.get"" + IL_0111: stloc.s V_5 + IL_0113: ldloca.s V_5 + IL_0115: call ""string int.ToString()"" + IL_011a: ldstr "" "" + IL_011f: ldloc.2 + IL_0120: callvirt ""int D.Y.get"" + IL_0125: stloc.s V_5 + IL_0127: ldloca.s V_5 + IL_0129: call ""string int.ToString()"" + IL_012e: call ""string string.Concat(string, string, string)"" + IL_0133: call ""void System.Console.WriteLine(string)"" + IL_0138: ret +}"); + } + private static ImmutableArray GetProperties(CSharpCompilation comp, string typeName) { return comp.GetMember(typeName).GetMembers().WhereAsArray(m => m.Kind == SymbolKind.Property); @@ -23557,8 +23767,10 @@ record B : A; Diagnostic(ErrorCode.ERR_CantOverrideNonVirtual, "B").WithArguments("B.EqualityContract", "A.EqualityContract").WithLocation(5, 8)); } - [Fact] - public void Equality_14() + [Theory] + [InlineData(TargetFramework.NetCoreApp)] + [InlineData(TargetFramework.Standard)] + public void Equality_14(TargetFramework targetFramework) { var source = @"record A; @@ -23568,7 +23780,7 @@ record B : A } record C : B; "; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, targetFramework: targetFramework); comp.VerifyDiagnostics( // (4,43): error CS8872: 'B.EqualityContract' must allow overriding because the containing record is not sealed. // protected sealed override System.Type EqualityContract => typeof(B); @@ -23577,6 +23789,22 @@ record C : B; // record C : B; Diagnostic(ErrorCode.ERR_CantOverrideSealed, "C").WithArguments("C.EqualityContract", "B.EqualityContract").WithLocation(6, 8)); + string expectedClone; + if (targetFramework == TargetFramework.Standard) + { + Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else if (targetFramework == TargetFramework.NetCoreApp) + { + Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; + } + else + { + throw ExceptionUtilities.Unreachable; + } + var actualMembers = comp.GetMember("B").GetMembers().ToTestDisplayStrings(); var expectedMembers = new[] { @@ -23590,7 +23818,7 @@ record C : B; "System.Boolean B.Equals(System.Object? obj)", "System.Boolean B.Equals(A? other)", "System.Boolean B.Equals(B? other)", - "A B." + WellKnownMemberNames.CloneMethodName + "()", + expectedClone, "B..ctor(B original)", "B..ctor()", }; @@ -25634,7 +25862,7 @@ public static void Main() [Fact] public void AccessCheckProtected03() { - CSharpCompilation c = CreateCompilation(@" + const string src = @" record X { } record A { } @@ -25649,8 +25877,8 @@ public record E { } } } } -"); - +"; + CSharpCompilation c = CreateCompilation(src); c.VerifyDiagnostics( // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' // record C : X @@ -25662,6 +25890,16 @@ public record E { } // record C : X Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) ); + + c = CreateCompilationWithCovariantReturns(src); + c.VerifyDiagnostics( + // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C").WithArguments("B.C", "X").WithLocation(8, 12), + // (8,12): error CS0051: Inconsistent accessibility: parameter type 'X' is less accessible than method 'B.C.Equals(X?)' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) + ); } [Fact] @@ -26019,6 +26257,19 @@ public partial record C1 // partial record C1 : NV Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) ); + + comp = CreateCompilationWithCovariantReturns(text); + comp.VerifyDiagnostics( + // (2,15): error CS0106: The modifier 'static' is not valid for this item + // static record NV + Diagnostic(ErrorCode.ERR_BadMemberFlag, "NV").WithArguments("static").WithLocation(2, 15), + // (6,23): error CS0051: Inconsistent accessibility: parameter type 'NV' is less accessible than method 'C1.Equals(NV?)' + // public partial record C1 + Diagnostic(ErrorCode.ERR_BadVisParamType, "C1").WithArguments("C1.Equals(NV?)", "NV").WithLocation(6, 23), + // (10,16): error CS0060: Inconsistent accessibility: base class 'NV' is less accessible than class 'C1' + // partial record C1 : NV + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) + ); } [Fact] From 54ae43661af279d3473d75e55be4a508fdab6e98 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 09:22:46 +0200 Subject: [PATCH 03/16] Fix tests --- src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 1ef6d402bdae8..2405a0353e6c5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -10827,6 +10827,7 @@ record C(object P) public object get_P() => null; public object set_Q() => null; }"; + CSharpTestSource testSource = targetFramework == TargetFramework.Standard ? new[] { source, IsExternalInitTypeDefinition } : source; var comp = CreateCompilation(source, targetFramework: targetFramework); comp.VerifyDiagnostics( // (9,17): error CS0082: Type 'C' already reserves a member called 'get_P' with the same parameter types @@ -15926,7 +15927,8 @@ public void Overrides_02(TargetFramework targetFramework) record B(int X, int Y) : A { }"; - var comp = CreateCompilation(source, targetFramework: targetFramework); + CSharpTestSource testSource = targetFramework == TargetFramework.Standard ? new[] { source, IsExternalInitTypeDefinition } : source; + var comp = CreateCompilation(testSource, targetFramework: targetFramework); comp.VerifyDiagnostics( // (3,35): error CS0111: Type 'A' already defines a member called 'Equals' with the same parameter types // public abstract override bool Equals(object other); From c46f7fba30004902f43ef8039abeb68dcad35871 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 09:44:55 +0200 Subject: [PATCH 04/16] Fix test --- src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 2405a0353e6c5..674e97729c620 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -10828,7 +10828,7 @@ record C(object P) public object set_Q() => null; }"; CSharpTestSource testSource = targetFramework == TargetFramework.Standard ? new[] { source, IsExternalInitTypeDefinition } : source; - var comp = CreateCompilation(source, targetFramework: targetFramework); + var comp = CreateCompilation(testSource, targetFramework: targetFramework); comp.VerifyDiagnostics( // (9,17): error CS0082: Type 'C' already reserves a member called 'get_P' with the same parameter types // record C(object P) From 173760e85dd8efd0916927fb7c497e1237092dd2 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 10:06:51 +0200 Subject: [PATCH 05/16] Add test --- .../Test/Semantic/Semantics/RecordTests.cs | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 674e97729c620..3b0d48e5124f5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -30171,5 +30171,106 @@ class C2 : I(0) Diagnostic(ErrorCode.ERR_UnexpectedArgumentList, "(0)").WithLocation(10, 13) ); } + + [Theory, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")] + [CombinatorialData] + public void CrossAssemblySupportingAndNotSupportingCovariantReturns(bool useCompilationReference) + { + var sourceA = +@"public record B(int I) +{ +} + +public record C(int I) : B(I);"; + + var compA = CreateCompilation(sourceA); + compA.VerifyDiagnostics(); + Assert.False(compA.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + var actualMembers = compA.GetMember("C").GetMembers().ToTestDisplayStrings(); + var expectedMembers = new[] + { + "C..ctor(System.Int32 I)", + "System.Type C.EqualityContract.get", + "System.Type C.EqualityContract { get; }", + "System.String C.ToString()", + "System.Boolean C." + WellKnownMemberNames.PrintMembersMethodName + "(System.Text.StringBuilder builder)", + "System.Boolean C.op_Inequality(C? left, C? right)", + "System.Boolean C.op_Equality(C? left, C? right)", + "System.Int32 C.GetHashCode()", + "System.Boolean C.Equals(System.Object? obj)", + "System.Boolean C.Equals(B? other)", + "System.Boolean C.Equals(C? other)", + "B C." + WellKnownMemberNames.CloneMethodName + "()", + "C..ctor(C original)", + "void C.Deconstruct(out System.Int32 I)", + }; + AssertEx.Equal(expectedMembers, actualMembers); + + var refA = useCompilationReference ? compA.ToMetadataReference() : compA.EmitToImageReference(); + + var sourceB = "record D(int I) : C(I);"; + + var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.NetCoreApp); + + if (useCompilationReference) + { + compB.VerifyDiagnostics( + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), + // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy + Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1)); + } + else + { + compB.VerifyDiagnostics(); + } + + Assert.True(compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + + actualMembers = compB.GetMember("D").GetMembers().ToTestDisplayStrings(); + expectedMembers = new[] + { + "D..ctor(System.Int32 I)", + "System.Type D.EqualityContract.get", + "System.Type D.EqualityContract { get; }", + "System.String D.ToString()", + "System.Boolean D." + WellKnownMemberNames.PrintMembersMethodName + "(System.Text.StringBuilder builder)", + "System.Boolean D.op_Inequality(D? left, D? right)", + "System.Boolean D.op_Equality(D? left, D? right)", + "System.Int32 D.GetHashCode()", + "System.Boolean D.Equals(System.Object? obj)", + "System.Boolean D.Equals(C? other)", + "System.Boolean D.Equals(D? other)", + "D D." + WellKnownMemberNames.CloneMethodName + "()", + "D..ctor(D original)", + "void D.Deconstruct(out System.Int32 I)" + }; + AssertEx.Equal(expectedMembers, actualMembers); + + } } } From e9c6c3546edb79da1e8b25414f8533d95e840ebd Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 16:36:52 +0200 Subject: [PATCH 06/16] Address feedback --- .../Test/Semantic/Semantics/RecordTests.cs | 103 ++++-------------- 1 file changed, 21 insertions(+), 82 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 3b0d48e5124f5..0350b7db60b13 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -24,10 +24,6 @@ private static CSharpCompilation CreateCompilation(CSharpTestSource source) => CSharpTestBase.CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview); - private static CSharpCompilation CreateCompilationWithCovariantReturns(CSharpTestSource source) - => CSharpTestBase.CreateCompilation(new[] { source }, - parseOptions: TestOptions.RegularPreview, targetFramework: TargetFramework.NetCoreApp); - private CompilationVerifier CompileAndVerify( CSharpTestSource src, string? expectedOutput = null, @@ -10808,10 +10804,8 @@ record C(object P1, object P2) : B AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers); } - [Theory] - [InlineData(TargetFramework.NetCoreApp)] - [InlineData(TargetFramework.Standard)] - public void Inheritance_24(TargetFramework targetFramework) + [Fact] + public void Inheritance_24() { var source = @"record A @@ -10827,28 +10821,15 @@ record C(object P) public object get_P() => null; public object set_Q() => null; }"; - CSharpTestSource testSource = targetFramework == TargetFramework.Standard ? new[] { source, IsExternalInitTypeDefinition } : source; - var comp = CreateCompilation(testSource, targetFramework: targetFramework); + var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (9,17): error CS0082: Type 'C' already reserves a member called 'get_P' with the same parameter types // record C(object P) Diagnostic(ErrorCode.ERR_MemberReserved, "P").WithArguments("get_P", "C").WithLocation(9, 17)); - string expectedClone; - if (targetFramework == TargetFramework.Standard) - { - Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else if (targetFramework == TargetFramework.NetCoreApp) - { - Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else - { - throw ExceptionUtilities.Unreachable; - } + var expectedClone = comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses + ? "B B." + WellKnownMemberNames.CloneMethodName + "()" + : "A B." + WellKnownMemberNames.CloneMethodName + "()"; var expectedMembers = new[] { @@ -12708,18 +12689,15 @@ .maxstack 8 } [Theory, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")] - [InlineData(false, TargetFramework.Standard)] - [InlineData(false, TargetFramework.NetCoreApp)] - [InlineData(true, TargetFramework.Standard)] - [InlineData(true, TargetFramework.NetCoreApp)] - public void CopyCtor(bool useCompilationReference, TargetFramework targetFramework) + [InlineData(false)] + [InlineData(true)] + public void CopyCtor(bool useCompilationReference) { var sourceA = @"public record B(object N1, object N2) { }"; - CSharpTestSource testSourceA = targetFramework == TargetFramework.Standard ? new[] { sourceA, IsExternalInitTypeDefinition } : sourceA; - var compA = CreateCompilation(testSourceA, targetFramework: targetFramework); + var compA = CreateCompilation(sourceA, targetFramework: TargetFramework.StandardLatest); var verifierA = CompileAndVerify(compA, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); verifierA.VerifyIL("B..ctor(B)", @" @@ -12758,8 +12736,7 @@ static void Main() System.Console.Write((c3.P1, c3.P2, c3.N1, c3.N2)); } }"; - CSharpTestSource testSourceB = targetFramework == TargetFramework.Standard ? new[] { sourceB, IsExternalInitTypeDefinition } : sourceB; - var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: targetFramework); + var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.StandardLatest); var verifierB = CompileAndVerify(compB, expectedOutput: "(1, 2, 3, 4) (1, 2, 3, 4) (10, 2, 30, 4)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); // call base copy constructor B..ctor(B) @@ -15912,10 +15889,8 @@ record B(int X, int Y) : A AssertEx.Equal(expectedMembers, actualMembers); } - [Theory] - [InlineData(TargetFramework.NetCoreApp)] - [InlineData(TargetFramework.Standard)] - public void Overrides_02(TargetFramework targetFramework) + [Fact] + public void Overrides_02() { var source = @"abstract record A @@ -15927,8 +15902,7 @@ public void Overrides_02(TargetFramework targetFramework) record B(int X, int Y) : A { }"; - CSharpTestSource testSource = targetFramework == TargetFramework.Standard ? new[] { source, IsExternalInitTypeDefinition } : source; - var comp = CreateCompilation(testSource, targetFramework: targetFramework); + var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (3,35): error CS0111: Type 'A' already defines a member called 'Equals' with the same parameter types // public abstract override bool Equals(object other); @@ -15938,21 +15912,9 @@ record B(int X, int Y) : A Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.Equals(object)").WithLocation(7, 8) ); - string expectedClone; - if (targetFramework == TargetFramework.Standard) - { - Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else if (targetFramework == TargetFramework.NetCoreApp) - { - Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else - { - throw ExceptionUtilities.Unreachable; - } + string expectedClone = comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses + ? "B B." + WellKnownMemberNames.CloneMethodName + "()" + : "A B." + WellKnownMemberNames.CloneMethodName + "()"; var actualMembers = comp.GetMember("B").GetMembers().ToTestDisplayStrings(); var expectedMembers = new[] @@ -21134,7 +21096,7 @@ public record C public int X { get; init; } } public record D(int Y) : C;"; - var comp = CreateCompilation(src, targetFramework: TargetFramework.NetCoreApp); + var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics(); var src2 = @" @@ -21172,7 +21134,7 @@ public static void Main() 1 2 2 3 3 2 -4 3", targetFramework: TargetFramework.NetCoreApp).VerifyDiagnostics(); +4 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics(); verifier.VerifyIL("E.Main", @" { @@ -25880,7 +25842,7 @@ public record E { } } } "; - CSharpCompilation c = CreateCompilation(src); + CSharpCompilation c = CreateCompilation(src, targetFramework: TargetFramework.StandardLatest); c.VerifyDiagnostics( // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' // record C : X @@ -25892,16 +25854,6 @@ public record E { } // record C : X Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) ); - - c = CreateCompilationWithCovariantReturns(src); - c.VerifyDiagnostics( - // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' - // record C : X - Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C").WithArguments("B.C", "X").WithLocation(8, 12), - // (8,12): error CS0051: Inconsistent accessibility: parameter type 'X' is less accessible than method 'B.C.Equals(X?)' - // record C : X - Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) - ); } [Fact] @@ -26244,7 +26196,7 @@ public partial record C1 { } "; - var comp = CreateCompilation(text); + var comp = CreateCompilation(text, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (2,15): error CS0106: The modifier 'static' is not valid for this item // static record NV @@ -26259,19 +26211,6 @@ public partial record C1 // partial record C1 : NV Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) ); - - comp = CreateCompilationWithCovariantReturns(text); - comp.VerifyDiagnostics( - // (2,15): error CS0106: The modifier 'static' is not valid for this item - // static record NV - Diagnostic(ErrorCode.ERR_BadMemberFlag, "NV").WithArguments("static").WithLocation(2, 15), - // (6,23): error CS0051: Inconsistent accessibility: parameter type 'NV' is less accessible than method 'C1.Equals(NV?)' - // public partial record C1 - Diagnostic(ErrorCode.ERR_BadVisParamType, "C1").WithArguments("C1.Equals(NV?)", "NV").WithLocation(6, 23), - // (10,16): error CS0060: Inconsistent accessibility: base class 'NV' is less accessible than class 'C1' - // partial record C1 : NV - Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) - ); } [Fact] From 48ccab1c73741612fc23e9501a86ca71ed12a359 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 16:45:08 +0200 Subject: [PATCH 07/16] Restore empty line --- src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 0350b7db60b13..611f7e7667af3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -372,6 +372,7 @@ record R3([System.Diagnostics.CodeAnalysis.NotNull] R3 x); // record R3([System.Diagnostics.CodeAnalysis.NotNull] R3 x); Diagnostic(ErrorCode.ERR_RecordAmbigCtor, "R3").WithLocation(7, 8) ); + var r = comp.GlobalNamespace.GetTypeMember("R"); Assert.Equal(new[] { "R..ctor(R x)", "R..ctor(R original)" }, r.GetMembers(".ctor").ToTestDisplayStrings()); } From 37cf2a4adfce44dab57304c0029f11d7f356f644 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 17:22:42 +0200 Subject: [PATCH 08/16] More test fixes --- .../Test/Semantic/Semantics/RecordTests.cs | 120 +++++++++++------- 1 file changed, 72 insertions(+), 48 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 611f7e7667af3..d4fd578439eea 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -10828,6 +10828,8 @@ record C(object P) // record C(object P) Diagnostic(ErrorCode.ERR_MemberReserved, "P").WithArguments("get_P", "C").WithLocation(9, 17)); + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + var expectedClone = comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses ? "B B." + WellKnownMemberNames.CloneMethodName + "()" : "A B." + WellKnownMemberNames.CloneMethodName + "()"; @@ -15913,6 +15915,7 @@ record B(int X, int Y) : A Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.Equals(object)").WithLocation(7, 8) ); + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); string expectedClone = comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses ? "B B." + WellKnownMemberNames.CloneMethodName + "()" : "A B." + WellKnownMemberNames.CloneMethodName + "()"; @@ -23732,10 +23735,8 @@ record B : A; Diagnostic(ErrorCode.ERR_CantOverrideNonVirtual, "B").WithArguments("B.EqualityContract", "A.EqualityContract").WithLocation(5, 8)); } - [Theory] - [InlineData(TargetFramework.NetCoreApp)] - [InlineData(TargetFramework.Standard)] - public void Equality_14(TargetFramework targetFramework) + [Fact] + public void Equality_14() { var source = @"record A; @@ -23745,7 +23746,7 @@ record B : A } record C : B; "; - var comp = CreateCompilation(source, targetFramework: targetFramework); + var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (4,43): error CS8872: 'B.EqualityContract' must allow overriding because the containing record is not sealed. // protected sealed override System.Type EqualityContract => typeof(B); @@ -23754,21 +23755,11 @@ record C : B; // record C : B; Diagnostic(ErrorCode.ERR_CantOverrideSealed, "C").WithArguments("C.EqualityContract", "B.EqualityContract").WithLocation(6, 8)); - string expectedClone; - if (targetFramework == TargetFramework.Standard) - { - Assert.False(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "A B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else if (targetFramework == TargetFramework.NetCoreApp) - { - Assert.True(comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); - expectedClone = "B B." + WellKnownMemberNames.CloneMethodName + "()"; - } - else - { - throw ExceptionUtilities.Unreachable; - } + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + + string expectedClone = comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses + ? "B B." + WellKnownMemberNames.CloneMethodName + "()" + : "A B." + WellKnownMemberNames.CloneMethodName + "()"; var actualMembers = comp.GetMember("B").GetMembers().ToTestDisplayStrings(); var expectedMembers = new[] @@ -25844,17 +25835,32 @@ public record E { } } "; CSharpCompilation c = CreateCompilation(src, targetFramework: TargetFramework.StandardLatest); - c.VerifyDiagnostics( - // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' - // record C : X - Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C").WithArguments("B.C", "X").WithLocation(8, 12), - // (8,12): error CS0050: Inconsistent accessibility: return type 'X' is less accessible than method 'B.C.$()' - // record C : X - Diagnostic(ErrorCode.ERR_BadVisReturnType, "C").WithArguments("B.C.$()", "X").WithLocation(8, 12), - // (8,12): error CS0051: Inconsistent accessibility: parameter type 'X' is less accessible than method 'B.C.Equals(X?)' - // record C : X - Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) - ); + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, c.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + if (c.Assembly.RuntimeSupportsCovariantReturnsOfClasses) + { + c.VerifyDiagnostics( + // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C").WithArguments("B.C", "X").WithLocation(8, 12), + // (8,12): error CS0051: Inconsistent accessibility: parameter type 'X' is less accessible than method 'B.C.Equals(X?)' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) + ); + } + else + { + c.VerifyDiagnostics( + // (8,12): error CS0060: Inconsistent accessibility: base type 'X' is less accessible than class 'B.C' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C").WithArguments("B.C", "X").WithLocation(8, 12), + // (8,12): error CS0050: Inconsistent accessibility: return type 'X' is less accessible than method 'B.C.$()' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisReturnType, "C").WithArguments("B.C.$()", "X").WithLocation(8, 12), + // (8,12): error CS0051: Inconsistent accessibility: parameter type 'X' is less accessible than method 'B.C.Equals(X?)' + // record C : X + Diagnostic(ErrorCode.ERR_BadVisParamType, "C").WithArguments("B.C.Equals(X?)", "X").WithLocation(8, 12) + ); + } } [Fact] @@ -26198,20 +26204,38 @@ public partial record C1 } "; var comp = CreateCompilation(text, targetFramework: TargetFramework.StandardLatest); - comp.VerifyDiagnostics( - // (2,15): error CS0106: The modifier 'static' is not valid for this item - // static record NV - Diagnostic(ErrorCode.ERR_BadMemberFlag, "NV").WithArguments("static").WithLocation(2, 15), - // (6,23): error CS0050: Inconsistent accessibility: return type 'NV' is less accessible than method 'C1.$()' - // public partial record C1 - Diagnostic(ErrorCode.ERR_BadVisReturnType, "C1").WithArguments("C1.$()", "NV").WithLocation(6, 23), - // (6,23): error CS0051: Inconsistent accessibility: parameter type 'NV' is less accessible than method 'C1.Equals(NV?)' - // public partial record C1 - Diagnostic(ErrorCode.ERR_BadVisParamType, "C1").WithArguments("C1.Equals(NV?)", "NV").WithLocation(6, 23), - // (10,16): error CS0060: Inconsistent accessibility: base class 'NV' is less accessible than class 'C1' - // partial record C1 : NV - Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) - ); + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + if (comp.Assembly.RuntimeSupportsCovariantReturnsOfClasses) + { + comp.VerifyDiagnostics( + // (2,15): error CS0106: The modifier 'static' is not valid for this item + // static record NV + Diagnostic(ErrorCode.ERR_BadMemberFlag, "NV").WithArguments("static").WithLocation(2, 15), + // (6,23): error CS0051: Inconsistent accessibility: parameter type 'NV' is less accessible than method 'C1.Equals(NV?)' + // public partial record C1 + Diagnostic(ErrorCode.ERR_BadVisParamType, "C1").WithArguments("C1.Equals(NV?)", "NV").WithLocation(6, 23), + // (10,16): error CS0060: Inconsistent accessibility: base class 'NV' is less accessible than class 'C1' + // partial record C1 : NV + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) + ); + } + else + { + comp.VerifyDiagnostics( + // (2,15): error CS0106: The modifier 'static' is not valid for this item + // static record NV + Diagnostic(ErrorCode.ERR_BadMemberFlag, "NV").WithArguments("static").WithLocation(2, 15), + // (6,23): error CS0050: Inconsistent accessibility: return type 'NV' is less accessible than method 'C1.$()' + // public partial record C1 + Diagnostic(ErrorCode.ERR_BadVisReturnType, "C1").WithArguments("C1.$()", "NV").WithLocation(6, 23), + // (6,23): error CS0051: Inconsistent accessibility: parameter type 'NV' is less accessible than method 'C1.Equals(NV?)' + // public partial record C1 + Diagnostic(ErrorCode.ERR_BadVisParamType, "C1").WithArguments("C1.Equals(NV?)", "NV").WithLocation(6, 23), + // (10,16): error CS0060: Inconsistent accessibility: base class 'NV' is less accessible than class 'C1' + // partial record C1 : NV + Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 16) + ); + } } [Fact] @@ -30123,7 +30147,7 @@ public void CrossAssemblySupportingAndNotSupportingCovariantReturns(bool useComp public record C(int I) : B(I);"; - var compA = CreateCompilation(sourceA); + var compA = CreateCompilation(new[] { sourceA, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.NetStandard20); compA.VerifyDiagnostics(); Assert.False(compA.Assembly.RuntimeSupportsCovariantReturnsOfClasses); var actualMembers = compA.GetMember("C").GetMembers().ToTestDisplayStrings(); @@ -30150,7 +30174,7 @@ public record C(int I) : B(I);"; var sourceB = "record D(int I) : C(I);"; - var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.NetCoreApp); + var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.StandardLatest); if (useCompilationReference) { @@ -30189,7 +30213,7 @@ public record C(int I) : B(I);"; compB.VerifyDiagnostics(); } - Assert.True(compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); actualMembers = compB.GetMember("D").GetMembers().ToTestDisplayStrings(); expectedMembers = new[] From c08d38d0aa51f995b8930d6d133f598e020c6e68 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 17:35:26 +0200 Subject: [PATCH 09/16] VerifyIL of clone --- .../CSharp/Test/Semantic/Semantics/RecordTests.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index d4fd578439eea..958f1c0b96484 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -12760,6 +12760,15 @@ .maxstack 2 IL_001a: stfld ""object C.k__BackingField"" IL_001f: ret }"); + + verifierA.VerifyIL($"B.{WellKnownMemberNames.CloneMethodName}()", @" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: newobj ""B..ctor(B)"" + IL_0006: ret +}"); } [Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")] @@ -25818,7 +25827,7 @@ public static void Main() [Fact] public void AccessCheckProtected03() { - const string src = @" + CSharpCompilation c = CreateCompilation(@" record X { } record A { } @@ -25833,8 +25842,7 @@ public record E { } } } } -"; - CSharpCompilation c = CreateCompilation(src, targetFramework: TargetFramework.StandardLatest); +", targetFramework: TargetFramework.StandardLatest); Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, c.Assembly.RuntimeSupportsCovariantReturnsOfClasses); if (c.Assembly.RuntimeSupportsCovariantReturnsOfClasses) { From 2b0d088ea8d38e44cf25baaa56765b0221846324 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 17:51:51 +0200 Subject: [PATCH 10/16] Fix test --- .../Test/Semantic/Semantics/RecordTests.cs | 42 ++----------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 958f1c0b96484..ad4da556a76c7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -30182,45 +30182,9 @@ public record C(int I) : B(I);"; var sourceB = "record D(int I) : C(I);"; - var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.StandardLatest); - - if (useCompilationReference) - { - compB.VerifyDiagnostics( - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1), - // warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'e2c3c06c-08d0-4c94-8ce0-425103d97081' matches identity 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy - Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "e2c3c06c-08d0-4c94-8ce0-425103d97081", "System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Runtime").WithLocation(1, 1)); - } - else - { - compB.VerifyDiagnostics(); - } - + // CS1701: Assuming assembly reference '{0}' used by '{1}' matches identity '{2}' of '{3}', you may need to supply runtime policy + var compB = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseDll.WithSpecificDiagnosticOptions("CS1701", ReportDiagnostic.Suppress), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.StandardLatest); + compB.VerifyDiagnostics(); Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); actualMembers = compB.GetMember("D").GetMembers().ToTestDisplayStrings(); From 3723cba76d27f9452af78f83d6481d998ee5927c Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Fri, 14 May 2021 18:36:37 +0200 Subject: [PATCH 11/16] Fix few tests --- .../CSharp/Test/Semantic/Semantics/RecordTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index ad4da556a76c7..aaa141d10b2c8 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -10822,7 +10822,7 @@ record C(object P) public object get_P() => null; public object set_Q() => null; }"; - var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardLatest); + var comp = CreateCompilation(RuntimeUtilities.IsCoreClrRuntime ? source : new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (9,17): error CS0082: Type 'C' already reserves a member called 'get_P' with the same parameter types // record C(object P) @@ -12700,7 +12700,7 @@ public void CopyCtor(bool useCompilationReference) @"public record B(object N1, object N2) { }"; - var compA = CreateCompilation(sourceA, targetFramework: TargetFramework.StandardLatest); + var compA = CreateCompilation(RuntimeUtilities.IsCoreClrRuntime ? sourceA : new[] { sourceA, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.StandardLatest); var verifierA = CompileAndVerify(compA, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); verifierA.VerifyIL("B..ctor(B)", @" @@ -12739,7 +12739,7 @@ static void Main() System.Console.Write((c3.P1, c3.P2, c3.N1, c3.N2)); } }"; - var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.StandardLatest); + var compB = CreateCompilation(RuntimeUtilities.IsCoreClrRuntime ? sourceB : new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.Regular9, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.StandardLatest); var verifierB = CompileAndVerify(compB, expectedOutput: "(1, 2, 3, 4) (1, 2, 3, 4) (10, 2, 30, 4)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails).VerifyDiagnostics(); // call base copy constructor B..ctor(B) @@ -15914,7 +15914,7 @@ public void Overrides_02() record B(int X, int Y) : A { }"; - var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardLatest); + var comp = CreateCompilation(RuntimeUtilities.IsCoreClrRuntime ? source : new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics( // (3,35): error CS0111: Type 'A' already defines a member called 'Equals' with the same parameter types // public abstract override bool Equals(object other); @@ -21109,7 +21109,7 @@ public record C public int X { get; init; } } public record D(int Y) : C;"; - var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardLatest); + var comp = CreateCompilation(RuntimeUtilities.IsCoreClrRuntime ? src : new[] { src, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.StandardLatest); comp.VerifyDiagnostics(); var src2 = @" @@ -21139,7 +21139,7 @@ public static void Main() Console.WriteLine(d2.X + "" "" + d2.Y); } }"; - var verifier = CompileAndVerify(src2, + var verifier = CompileAndVerify(RuntimeUtilities.IsCoreClrRuntime ? src2 : new[] { src2, IsExternalInitTypeDefinition }, references: new[] { emitRef ? comp.EmitToImageReference() : comp.ToMetadataReference() }, expectedOutput: @" 1 From 55db7dac6017522ed9df89cbf07291c9eb4bdea4 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Tue, 18 May 2021 20:20:06 +0200 Subject: [PATCH 12/16] Fix test --- .../Test/Semantic/Semantics/RecordTests.cs | 126 +++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index aaa141d10b2c8..2ab12a2386b5d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -21148,8 +21148,9 @@ 1 2 2 3 3 2 4 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics(); - - verifier.VerifyIL("E.Main", @" + if (RuntimeUtilities.IsCoreClrRuntime) + { + verifier.VerifyIL("E.Main", @" { // Code size 313 (0x139) .maxstack 3 @@ -21265,6 +21266,127 @@ .locals init (C V_0, //c IL_0133: call ""void System.Console.WriteLine(string)"" IL_0138: ret }"); + } + else + { + verifier.VerifyIL("E.Main", @" +{ + // Code size 318 (0x13e) + .maxstack 3 + .locals init (C V_0, //c + D V_1, //d + D V_2, //d2 + C V_3, //c3 + C V_4, //c4 + int V_5) + IL_0000: newobj ""C..ctor()"" + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: callvirt ""void C.X.init"" + IL_000c: stloc.0 + IL_000d: ldloc.0 + IL_000e: callvirt ""C C.$()"" + IL_0013: dup + IL_0014: ldc.i4.2 + IL_0015: callvirt ""void C.X.init"" + IL_001a: ldloc.0 + IL_001b: callvirt ""int C.X.get"" + IL_0020: call ""void System.Console.WriteLine(int)"" + IL_0025: callvirt ""int C.X.get"" + IL_002a: call ""void System.Console.WriteLine(int)"" + IL_002f: ldc.i4.2 + IL_0030: newobj ""D..ctor(int)"" + IL_0035: dup + IL_0036: ldc.i4.1 + IL_0037: callvirt ""void C.X.init"" + IL_003c: stloc.1 + IL_003d: ldloc.1 + IL_003e: callvirt ""C C.$()"" + IL_0043: castclass ""D"" + IL_0048: dup + IL_0049: ldc.i4.2 + IL_004a: callvirt ""void C.X.init"" + IL_004f: dup + IL_0050: ldc.i4.3 + IL_0051: callvirt ""void D.Y.init"" + IL_0056: stloc.2 + IL_0057: ldloc.1 + IL_0058: callvirt ""int C.X.get"" + IL_005d: stloc.s V_5 + IL_005f: ldloca.s V_5 + IL_0061: call ""string int.ToString()"" + IL_0066: ldstr "" "" + IL_006b: ldloc.1 + IL_006c: callvirt ""int D.Y.get"" + IL_0071: stloc.s V_5 + IL_0073: ldloca.s V_5 + IL_0075: call ""string int.ToString()"" + IL_007a: call ""string string.Concat(string, string, string)"" + IL_007f: call ""void System.Console.WriteLine(string)"" + IL_0084: ldloc.2 + IL_0085: callvirt ""int C.X.get"" + IL_008a: stloc.s V_5 + IL_008c: ldloca.s V_5 + IL_008e: call ""string int.ToString()"" + IL_0093: ldstr "" "" + IL_0098: ldloc.2 + IL_0099: callvirt ""int D.Y.get"" + IL_009e: stloc.s V_5 + IL_00a0: ldloca.s V_5 + IL_00a2: call ""string int.ToString()"" + IL_00a7: call ""string string.Concat(string, string, string)"" + IL_00ac: call ""void System.Console.WriteLine(string)"" + IL_00b1: ldloc.1 + IL_00b2: stloc.3 + IL_00b3: ldloc.2 + IL_00b4: stloc.s V_4 + IL_00b6: ldloc.3 + IL_00b7: callvirt ""C C.$()"" + IL_00bc: dup + IL_00bd: ldc.i4.3 + IL_00be: callvirt ""void C.X.init"" + IL_00c3: stloc.3 + IL_00c4: ldloc.s V_4 + IL_00c6: callvirt ""C C.$()"" + IL_00cb: dup + IL_00cc: ldc.i4.4 + IL_00cd: callvirt ""void C.X.init"" + IL_00d2: stloc.s V_4 + IL_00d4: ldloc.3 + IL_00d5: castclass ""D"" + IL_00da: stloc.1 + IL_00db: ldloc.s V_4 + IL_00dd: castclass ""D"" + IL_00e2: stloc.2 + IL_00e3: ldloc.1 + IL_00e4: callvirt ""int C.X.get"" + IL_00e9: stloc.s V_5 + IL_00eb: ldloca.s V_5 + IL_00ed: call ""string int.ToString()"" + IL_00f2: ldstr "" "" + IL_00f7: ldloc.1 + IL_00f8: callvirt ""int D.Y.get"" + IL_00fd: stloc.s V_5 + IL_00ff: ldloca.s V_5 + IL_0101: call ""string int.ToString()"" + IL_0106: call ""string string.Concat(string, string, string)"" + IL_010b: call ""void System.Console.WriteLine(string)"" + IL_0110: ldloc.2 + IL_0111: callvirt ""int C.X.get"" + IL_0116: stloc.s V_5 + IL_0118: ldloca.s V_5 + IL_011a: call ""string int.ToString()"" + IL_011f: ldstr "" "" + IL_0124: ldloc.2 + IL_0125: callvirt ""int D.Y.get"" + IL_012a: stloc.s V_5 + IL_012c: ldloca.s V_5 + IL_012e: call ""string int.ToString()"" + IL_0133: call ""string string.Concat(string, string, string)"" + IL_0138: call ""void System.Console.WriteLine(string)"" + IL_013d: ret +}"); + } } private static ImmutableArray GetProperties(CSharpCompilation comp, string typeName) From e3c369aa42cd5e333596660bfc715d95da04fada Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Tue, 1 Jun 2021 06:47:41 +0200 Subject: [PATCH 13/16] Fix test --- src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 2ab12a2386b5d..ca162f96acd91 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -30277,7 +30277,7 @@ public void CrossAssemblySupportingAndNotSupportingCovariantReturns(bool useComp public record C(int I) : B(I);"; - var compA = CreateCompilation(new[] { sourceA, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.NetStandard20); + var compA = CreateEmptyCompilation(new[] { sourceA, IsExternalInitTypeDefinition }, references: TargetFrameworkUtil.GetReferences(TargetFramework.NetStandard20)); compA.VerifyDiagnostics(); Assert.False(compA.Assembly.RuntimeSupportsCovariantReturnsOfClasses); var actualMembers = compA.GetMember("C").GetMembers().ToTestDisplayStrings(); @@ -30305,9 +30305,9 @@ public record C(int I) : B(I);"; var sourceB = "record D(int I) : C(I);"; // CS1701: Assuming assembly reference '{0}' used by '{1}' matches identity '{2}' of '{3}', you may need to supply runtime policy - var compB = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseDll.WithSpecificDiagnosticOptions("CS1701", ReportDiagnostic.Suppress), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.StandardLatest); + var compB = CreateCompilation(sourceB, references: new[] { refA }, options: TestOptions.ReleaseDll.WithSpecificDiagnosticOptions("CS1701", ReportDiagnostic.Suppress), parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.NetCoreApp); compB.VerifyDiagnostics(); - Assert.Equal(RuntimeUtilities.IsCoreClrRuntime, compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); + Assert.True(compB.Assembly.RuntimeSupportsCovariantReturnsOfClasses); actualMembers = compB.GetMember("D").GetMembers().ToTestDisplayStrings(); expectedMembers = new[] From d224dd25ced6d2a7ed545a57f1ec1e64c1e7c6a2 Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Wed, 23 Jun 2021 12:59:29 +0200 Subject: [PATCH 14/16] Simplify test --- .../Test/Semantic/Semantics/RecordTests.cs | 338 ++++++------------ 1 file changed, 101 insertions(+), 237 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index ca162f96acd91..16aeebd9f42d3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -21119,24 +21119,24 @@ class E public static void Main() { var c = new C() { X = 1 }; - var c2 = c with { X = 2 }; + var c2 = CHelper(c); Console.WriteLine(c.X); Console.WriteLine(c2.X); var d = new D(2) { X = 1 }; - var d2 = d with { X = 2, Y = 3 }; + var d2 = DHelper(d); Console.WriteLine(d.X + "" "" + d.Y); Console.WriteLine(d2.X + "" "" + d2.Y); + } - C c3 = d; - C c4 = d2; - c3 = c3 with { X = 3 }; - c4 = c4 with { X = 4 }; + private static C CHelper(C c) + { + return c with { X = 2 }; + } - d = (D)c3; - d2 = (D)c4; - Console.WriteLine(d.X + "" "" + d.Y); - Console.WriteLine(d2.X + "" "" + d2.Y); + private static D DHelper(D d) + { + return d with { X = 2, Y = 3 }; } }"; var verifier = CompileAndVerify(RuntimeUtilities.IsCoreClrRuntime ? src2 : new[] { src2, IsExternalInitTypeDefinition }, @@ -21145,247 +21145,111 @@ public static void Main() 1 2 1 2 -2 3 -3 2 -4 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics(); - if (RuntimeUtilities.IsCoreClrRuntime) - { - verifier.VerifyIL("E.Main", @" +2 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics().VerifyIL("E.Main", @" { - // Code size 313 (0x139) + // Code size 148 (0x94) .maxstack 3 - .locals init (C V_0, //c + .locals init (C V_0, //c2 D V_1, //d D V_2, //d2 - C V_3, //c3 - C V_4, //c4 - int V_5) + int V_3) IL_0000: newobj ""C..ctor()"" IL_0005: dup IL_0006: ldc.i4.1 IL_0007: callvirt ""void C.X.init"" - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: callvirt ""C C.$()"" - IL_0013: dup - IL_0014: ldc.i4.2 - IL_0015: callvirt ""void C.X.init"" - IL_001a: ldloc.0 - IL_001b: callvirt ""int C.X.get"" - IL_0020: call ""void System.Console.WriteLine(int)"" - IL_0025: callvirt ""int C.X.get"" - IL_002a: call ""void System.Console.WriteLine(int)"" - IL_002f: ldc.i4.2 - IL_0030: newobj ""D..ctor(int)"" - IL_0035: dup - IL_0036: ldc.i4.1 - IL_0037: callvirt ""void C.X.init"" - IL_003c: stloc.1 + IL_000c: dup + IL_000d: call ""C E.CHelper(C)"" + IL_0012: stloc.0 + IL_0013: callvirt ""int C.X.get"" + IL_0018: call ""void System.Console.WriteLine(int)"" + IL_001d: ldloc.0 + IL_001e: callvirt ""int C.X.get"" + IL_0023: call ""void System.Console.WriteLine(int)"" + IL_0028: ldc.i4.2 + IL_0029: newobj ""D..ctor(int)"" + IL_002e: dup + IL_002f: ldc.i4.1 + IL_0030: callvirt ""void C.X.init"" + IL_0035: stloc.1 + IL_0036: ldloc.1 + IL_0037: call ""D E.DHelper(D)"" + IL_003c: stloc.2 IL_003d: ldloc.1 - IL_003e: callvirt ""D D.$()"" - IL_0043: dup - IL_0044: ldc.i4.2 - IL_0045: callvirt ""void C.X.init"" - IL_004a: dup - IL_004b: ldc.i4.3 - IL_004c: callvirt ""void D.Y.init"" - IL_0051: stloc.2 - IL_0052: ldloc.1 - IL_0053: callvirt ""int C.X.get"" - IL_0058: stloc.s V_5 - IL_005a: ldloca.s V_5 - IL_005c: call ""string int.ToString()"" - IL_0061: ldstr "" "" - IL_0066: ldloc.1 - IL_0067: callvirt ""int D.Y.get"" - IL_006c: stloc.s V_5 - IL_006e: ldloca.s V_5 - IL_0070: call ""string int.ToString()"" - IL_0075: call ""string string.Concat(string, string, string)"" - IL_007a: call ""void System.Console.WriteLine(string)"" - IL_007f: ldloc.2 - IL_0080: callvirt ""int C.X.get"" - IL_0085: stloc.s V_5 - IL_0087: ldloca.s V_5 - IL_0089: call ""string int.ToString()"" - IL_008e: ldstr "" "" - IL_0093: ldloc.2 - IL_0094: callvirt ""int D.Y.get"" - IL_0099: stloc.s V_5 - IL_009b: ldloca.s V_5 - IL_009d: call ""string int.ToString()"" - IL_00a2: call ""string string.Concat(string, string, string)"" - IL_00a7: call ""void System.Console.WriteLine(string)"" - IL_00ac: ldloc.1 - IL_00ad: stloc.3 - IL_00ae: ldloc.2 - IL_00af: stloc.s V_4 - IL_00b1: ldloc.3 - IL_00b2: callvirt ""C C.$()"" - IL_00b7: dup - IL_00b8: ldc.i4.3 - IL_00b9: callvirt ""void C.X.init"" - IL_00be: stloc.3 - IL_00bf: ldloc.s V_4 - IL_00c1: callvirt ""C C.$()"" - IL_00c6: dup - IL_00c7: ldc.i4.4 - IL_00c8: callvirt ""void C.X.init"" - IL_00cd: stloc.s V_4 - IL_00cf: ldloc.3 - IL_00d0: castclass ""D"" - IL_00d5: stloc.1 - IL_00d6: ldloc.s V_4 - IL_00d8: castclass ""D"" - IL_00dd: stloc.2 - IL_00de: ldloc.1 - IL_00df: callvirt ""int C.X.get"" - IL_00e4: stloc.s V_5 - IL_00e6: ldloca.s V_5 - IL_00e8: call ""string int.ToString()"" - IL_00ed: ldstr "" "" - IL_00f2: ldloc.1 - IL_00f3: callvirt ""int D.Y.get"" - IL_00f8: stloc.s V_5 - IL_00fa: ldloca.s V_5 - IL_00fc: call ""string int.ToString()"" - IL_0101: call ""string string.Concat(string, string, string)"" - IL_0106: call ""void System.Console.WriteLine(string)"" - IL_010b: ldloc.2 - IL_010c: callvirt ""int C.X.get"" - IL_0111: stloc.s V_5 - IL_0113: ldloca.s V_5 - IL_0115: call ""string int.ToString()"" - IL_011a: ldstr "" "" - IL_011f: ldloc.2 - IL_0120: callvirt ""int D.Y.get"" - IL_0125: stloc.s V_5 - IL_0127: ldloca.s V_5 - IL_0129: call ""string int.ToString()"" - IL_012e: call ""string string.Concat(string, string, string)"" - IL_0133: call ""void System.Console.WriteLine(string)"" - IL_0138: ret -}"); + IL_003e: callvirt ""int C.X.get"" + IL_0043: stloc.3 + IL_0044: ldloca.s V_3 + IL_0046: call ""string int.ToString()"" + IL_004b: ldstr "" "" + IL_0050: ldloc.1 + IL_0051: callvirt ""int D.Y.get"" + IL_0056: stloc.3 + IL_0057: ldloca.s V_3 + IL_0059: call ""string int.ToString()"" + IL_005e: call ""string string.Concat(string, string, string)"" + IL_0063: call ""void System.Console.WriteLine(string)"" + IL_0068: ldloc.2 + IL_0069: callvirt ""int C.X.get"" + IL_006e: stloc.3 + IL_006f: ldloca.s V_3 + IL_0071: call ""string int.ToString()"" + IL_0076: ldstr "" "" + IL_007b: ldloc.2 + IL_007c: callvirt ""int D.Y.get"" + IL_0081: stloc.3 + IL_0082: ldloca.s V_3 + IL_0084: call ""string int.ToString()"" + IL_0089: call ""string string.Concat(string, string, string)"" + IL_008e: call ""void System.Console.WriteLine(string)"" + IL_0093: ret +} +").VerifyIL("E.CHelper", @" +{ + // Code size 14 (0xe) + .maxstack 3 + IL_0000: ldarg.0 + IL_0001: callvirt ""C C.$()"" + IL_0006: dup + IL_0007: ldc.i4.2 + IL_0008: callvirt ""void C.X.init"" + IL_000d: ret +} +"); + if (RuntimeUtilities.IsCoreClrRuntime) + { + verifier.VerifyIL("E.DHelper", @" +{ + // Code size 21 (0x15) + .maxstack 3 + IL_0000: ldarg.0 + IL_0001: callvirt ""D D.$()"" + IL_0006: dup + IL_0007: ldc.i4.2 + IL_0008: callvirt ""void C.X.init"" + IL_000d: dup + IL_000e: ldc.i4.3 + IL_000f: callvirt ""void D.Y.init"" + IL_0014: ret +} + "); } else { - verifier.VerifyIL("E.Main", @" + verifier.VerifyIL("E.DHelper", @" { - // Code size 318 (0x13e) + // Code size 26 (0x1a) .maxstack 3 - .locals init (C V_0, //c - D V_1, //d - D V_2, //d2 - C V_3, //c3 - C V_4, //c4 - int V_5) - IL_0000: newobj ""C..ctor()"" - IL_0005: dup - IL_0006: ldc.i4.1 - IL_0007: callvirt ""void C.X.init"" - IL_000c: stloc.0 - IL_000d: ldloc.0 - IL_000e: callvirt ""C C.$()"" - IL_0013: dup - IL_0014: ldc.i4.2 - IL_0015: callvirt ""void C.X.init"" - IL_001a: ldloc.0 - IL_001b: callvirt ""int C.X.get"" - IL_0020: call ""void System.Console.WriteLine(int)"" - IL_0025: callvirt ""int C.X.get"" - IL_002a: call ""void System.Console.WriteLine(int)"" - IL_002f: ldc.i4.2 - IL_0030: newobj ""D..ctor(int)"" - IL_0035: dup - IL_0036: ldc.i4.1 - IL_0037: callvirt ""void C.X.init"" - IL_003c: stloc.1 - IL_003d: ldloc.1 - IL_003e: callvirt ""C C.$()"" - IL_0043: castclass ""D"" - IL_0048: dup - IL_0049: ldc.i4.2 - IL_004a: callvirt ""void C.X.init"" - IL_004f: dup - IL_0050: ldc.i4.3 - IL_0051: callvirt ""void D.Y.init"" - IL_0056: stloc.2 - IL_0057: ldloc.1 - IL_0058: callvirt ""int C.X.get"" - IL_005d: stloc.s V_5 - IL_005f: ldloca.s V_5 - IL_0061: call ""string int.ToString()"" - IL_0066: ldstr "" "" - IL_006b: ldloc.1 - IL_006c: callvirt ""int D.Y.get"" - IL_0071: stloc.s V_5 - IL_0073: ldloca.s V_5 - IL_0075: call ""string int.ToString()"" - IL_007a: call ""string string.Concat(string, string, string)"" - IL_007f: call ""void System.Console.WriteLine(string)"" - IL_0084: ldloc.2 - IL_0085: callvirt ""int C.X.get"" - IL_008a: stloc.s V_5 - IL_008c: ldloca.s V_5 - IL_008e: call ""string int.ToString()"" - IL_0093: ldstr "" "" - IL_0098: ldloc.2 - IL_0099: callvirt ""int D.Y.get"" - IL_009e: stloc.s V_5 - IL_00a0: ldloca.s V_5 - IL_00a2: call ""string int.ToString()"" - IL_00a7: call ""string string.Concat(string, string, string)"" - IL_00ac: call ""void System.Console.WriteLine(string)"" - IL_00b1: ldloc.1 - IL_00b2: stloc.3 - IL_00b3: ldloc.2 - IL_00b4: stloc.s V_4 - IL_00b6: ldloc.3 - IL_00b7: callvirt ""C C.$()"" - IL_00bc: dup - IL_00bd: ldc.i4.3 - IL_00be: callvirt ""void C.X.init"" - IL_00c3: stloc.3 - IL_00c4: ldloc.s V_4 - IL_00c6: callvirt ""C C.$()"" - IL_00cb: dup - IL_00cc: ldc.i4.4 - IL_00cd: callvirt ""void C.X.init"" - IL_00d2: stloc.s V_4 - IL_00d4: ldloc.3 - IL_00d5: castclass ""D"" - IL_00da: stloc.1 - IL_00db: ldloc.s V_4 - IL_00dd: castclass ""D"" - IL_00e2: stloc.2 - IL_00e3: ldloc.1 - IL_00e4: callvirt ""int C.X.get"" - IL_00e9: stloc.s V_5 - IL_00eb: ldloca.s V_5 - IL_00ed: call ""string int.ToString()"" - IL_00f2: ldstr "" "" - IL_00f7: ldloc.1 - IL_00f8: callvirt ""int D.Y.get"" - IL_00fd: stloc.s V_5 - IL_00ff: ldloca.s V_5 - IL_0101: call ""string int.ToString()"" - IL_0106: call ""string string.Concat(string, string, string)"" - IL_010b: call ""void System.Console.WriteLine(string)"" - IL_0110: ldloc.2 - IL_0111: callvirt ""int C.X.get"" - IL_0116: stloc.s V_5 - IL_0118: ldloca.s V_5 - IL_011a: call ""string int.ToString()"" - IL_011f: ldstr "" "" - IL_0124: ldloc.2 - IL_0125: callvirt ""int D.Y.get"" - IL_012a: stloc.s V_5 - IL_012c: ldloca.s V_5 - IL_012e: call ""string int.ToString()"" - IL_0133: call ""string string.Concat(string, string, string)"" - IL_0138: call ""void System.Console.WriteLine(string)"" - IL_013d: ret -}"); + IL_0000: ldarg.0 + IL_0001: callvirt ""C C.$()"" + IL_0006: castclass ""D"" + IL_000b: dup + IL_000c: ldc.i4.2 + IL_000d: callvirt ""void C.X.init"" + IL_0012: dup + IL_0013: ldc.i4.3 + IL_0014: callvirt ""void D.Y.init"" + IL_0019: ret +} + "); } } From 8941ff452fb52e1e2b873f0d3dc4a29888dd408f Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Wed, 23 Jun 2021 19:41:00 +0200 Subject: [PATCH 15/16] Address feedback --- .../Test/Semantic/Semantics/RecordTests.cs | 59 +------------------ 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index 16aeebd9f42d3..04c8e5757fc3d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -21145,64 +21145,7 @@ private static D DHelper(D d) 1 2 1 2 -2 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics().VerifyIL("E.Main", @" -{ - // Code size 148 (0x94) - .maxstack 3 - .locals init (C V_0, //c2 - D V_1, //d - D V_2, //d2 - int V_3) - IL_0000: newobj ""C..ctor()"" - IL_0005: dup - IL_0006: ldc.i4.1 - IL_0007: callvirt ""void C.X.init"" - IL_000c: dup - IL_000d: call ""C E.CHelper(C)"" - IL_0012: stloc.0 - IL_0013: callvirt ""int C.X.get"" - IL_0018: call ""void System.Console.WriteLine(int)"" - IL_001d: ldloc.0 - IL_001e: callvirt ""int C.X.get"" - IL_0023: call ""void System.Console.WriteLine(int)"" - IL_0028: ldc.i4.2 - IL_0029: newobj ""D..ctor(int)"" - IL_002e: dup - IL_002f: ldc.i4.1 - IL_0030: callvirt ""void C.X.init"" - IL_0035: stloc.1 - IL_0036: ldloc.1 - IL_0037: call ""D E.DHelper(D)"" - IL_003c: stloc.2 - IL_003d: ldloc.1 - IL_003e: callvirt ""int C.X.get"" - IL_0043: stloc.3 - IL_0044: ldloca.s V_3 - IL_0046: call ""string int.ToString()"" - IL_004b: ldstr "" "" - IL_0050: ldloc.1 - IL_0051: callvirt ""int D.Y.get"" - IL_0056: stloc.3 - IL_0057: ldloca.s V_3 - IL_0059: call ""string int.ToString()"" - IL_005e: call ""string string.Concat(string, string, string)"" - IL_0063: call ""void System.Console.WriteLine(string)"" - IL_0068: ldloc.2 - IL_0069: callvirt ""int C.X.get"" - IL_006e: stloc.3 - IL_006f: ldloca.s V_3 - IL_0071: call ""string int.ToString()"" - IL_0076: ldstr "" "" - IL_007b: ldloc.2 - IL_007c: callvirt ""int D.Y.get"" - IL_0081: stloc.3 - IL_0082: ldloca.s V_3 - IL_0084: call ""string int.ToString()"" - IL_0089: call ""string string.Concat(string, string, string)"" - IL_008e: call ""void System.Console.WriteLine(string)"" - IL_0093: ret -} -").VerifyIL("E.CHelper", @" +2 3", targetFramework: TargetFramework.StandardLatest).VerifyDiagnostics().VerifyIL("E.CHelper", @" { // Code size 14 (0xe) .maxstack 3 From 85c48b75ce61b4d672d11d2d0c5a1ed5b722c4bf Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 25 Jun 2021 06:58:11 +0200 Subject: [PATCH 16/16] Address feedback --- .../Symbols/Synthesized/Records/SynthesizedRecordClone.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs index fee09b4ce5db3..5ddc18abecfce 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordClone.cs @@ -97,7 +97,7 @@ static bool modifiersAreValid(DeclarationModifiers modifiers) protected override (TypeWithAnnotations ReturnType, ImmutableArray Parameters, bool IsVararg, ImmutableArray DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics) { - return (ReturnType: VirtualCloneInBase() is { } baseClone && !ContainingAssembly.RuntimeSupportsCovariantReturnsOfClasses ? + return (ReturnType: !ContainingAssembly.RuntimeSupportsCovariantReturnsOfClasses && VirtualCloneInBase() is { } baseClone ? baseClone.ReturnTypeWithAnnotations : TypeWithAnnotations.Create(isNullableEnabled: true, ContainingType), Parameters: ImmutableArray.Empty,