未验证 提交 1fd21f84 编写于 作者: C Charles Stoner 提交者: GitHub

Make Inheritance_* tests contiguous (#45233)

上级 64b18bef
......@@ -3689,1426 +3689,1426 @@ .maxstack 3
}");
}
[Theory, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[InlineData(false)]
[InlineData(true)]
public void CopyCtor(bool useCompilationReference)
[Fact]
public void Inheritance_22()
{
var sourceA =
@"public record B(object N1, object N2)
var source =
@"record A
{
}";
var compA = CreateCompilation(sourceA);
var verifierA = CompileAndVerify(compA, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifierA.VerifyIL("B..ctor(B)", @"
public ref object P1 => throw null;
public object P2 => throw null;
}
record B : A
{
// Code size 31 (0x1f)
.maxstack 2
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: ldfld ""object B.<N1>k__BackingField""
IL_000d: stfld ""object B.<N1>k__BackingField""
IL_0012: ldarg.0
IL_0013: ldarg.1
IL_0014: ldfld ""object B.<N2>k__BackingField""
IL_0019: stfld ""object B.<N2>k__BackingField""
IL_001e: ret
}");
var refA = useCompilationReference ? compA.ToMetadataReference() : compA.EmitToImageReference();
var sourceB =
@"record C(object P1, object P2) : B(3, 4)
public new object P1 => throw null;
public new ref object P2 => throw null;
}
record C(object P1, object P2) : B
{
static void Main()
{
var c1 = new C(1, 2);
System.Console.Write((c1.P1, c1.P2, c1.N1, c1.N2));
System.Console.Write("" "");
var c2 = new C(c1);
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2));
System.Console.Write("" "");
var c3 = c1 with { P1 = 10, N1 = 30 };
System.Console.Write((c3.P1, c3.P2, c3.N1, c3.N2));
}
}";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
compB.VerifyDiagnostics();
var verifierB = CompileAndVerify(compB, expectedOutput: "(1, 2, 3, 4) (1, 2, 3, 4) (10, 2, 30, 4)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
// call base copy constructor B..ctor(B)
verifierB.VerifyIL("C..ctor(C)", @"
{
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}");
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(comp, "C").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithOtherOverload()
[Fact]
public void Inheritance_23()
{
var source =
@"public record B(object N1, object N2)
@"record A
{
public B(C c) : this(30, 40) => throw null;
public static object P1 { get; }
public object P2 { get; }
}
public record C(object P1, object P2) : B(3, 4)
record B : A
{
static void Main()
{
var c1 = new C(1, 2);
System.Console.Write((c1.P1, c1.P2, c1.N1, c1.N2));
System.Console.Write("" "");
var c2 = c1 with { P1 = 10, P2 = 20, N1 = 30, N2 = 40 };
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2));
}
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 3, 4) (10, 20, 30, 40)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
// call base copy constructor B..ctor(B)
verifier.VerifyIL("C..ctor(C)", @"
public new object P1 { get; }
public new static object P2 { get; }
}
record C(object P1, object P2) : B
{
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}");
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (11,28): error CS8866: Record member 'B.P2' must be a readable instance property of type 'object' to match positional parameter 'P2'.
// record C(object P1, object P2) : B
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P2").WithArguments("B.P2", "object", "P2").WithLocation(11, 28));
var actualMembers = GetProperties(comp, "C").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithObsoleteCopyConstructor()
[Fact]
public void Inheritance_24()
{
var source =
@"public record B(object N1, object N2)
@"record A
{
[System.Obsolete(""Obsolete"", true)]
public B(B b) { }
public object get_P() => null;
public object set_Q() => null;
}
public record C(object P1, object P2) : B(3, 4) { }
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithParamsCopyConstructor()
{
var source =
@"public record B(object N1, object N2)
record B(object P, object Q) : A
{
public B(B b, params int[] i) : this(30, 40) { }
}
public record C(object P1, object P2) : B(3, 4) { }
";
record C(object P)
{
public object get_P() => null;
public object set_Q() => null;
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
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));
var actualMembers = comp.GetMember<NamedTypeSymbol>("B").GetMembers().Where(m => m.Name == ".ctor").ToTestDisplayStrings();
var expectedMembers = new[]
{
"B..ctor(System.Object N1, System.Object N2)",
"B..ctor(B b, params System.Int32[] i)",
"B..ctor(B )"
"A B.<>Clone()",
"System.Type B.EqualityContract.get",
"System.Type B.EqualityContract { get; }",
"B..ctor(System.Object P, System.Object Q)",
"System.Object B.<P>k__BackingField",
"System.Object B.P.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) B.P.init",
"System.Object B.P { get; init; }",
"System.Object B.<Q>k__BackingField",
"System.Object B.Q.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) B.Q.init",
"System.Object B.Q { get; init; }",
"System.Int32 B.GetHashCode()",
"System.Boolean B.Equals(System.Object? )",
"System.Boolean B.Equals(A? )",
"System.Boolean B.Equals(B? )",
"B..ctor(B )",
"void B.Deconstruct(out System.Object P, out System.Object Q)"
};
AssertEx.Equal(expectedMembers, actualMembers);
AssertEx.Equal(expectedMembers, comp.GetMember<NamedTypeSymbol>("B").GetMembers().ToTestDisplayStrings());
var verifier = CompileAndVerify(comp, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}
");
expectedMembers = new[]
{
"C C.<>Clone()",
"System.Type C.EqualityContract.get",
"System.Type C.EqualityContract { get; }",
"C..ctor(System.Object P)",
"System.Object C.<P>k__BackingField",
"System.Object C.P.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) C.P.init",
"System.Object C.P { get; init; }",
"System.Object C.get_P()",
"System.Object C.set_Q()",
"System.Int32 C.GetHashCode()",
"System.Boolean C.Equals(System.Object? )",
"System.Boolean C.Equals(C? )",
"C..ctor(C )",
"void C.Deconstruct(out System.Object P)"
};
AssertEx.Equal(expectedMembers, comp.GetMember<NamedTypeSymbol>("C").GetMembers().ToTestDisplayStrings());
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithInitializers()
[Fact]
public void Inheritance_25()
{
var source =
@"public record C(object N1, object N2)
var sourceA =
@"public record A
{
private int field = 42;
public int Property = 43;
public class P1 { }
internal object P2 = 2;
public int P3(object o) => 3;
internal int P4<T>(T t) => 4;
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
var sourceB =
@"record B(object P1, object P2, object P3, object P4) : A
{
// Code size 55 (0x37)
.maxstack 2
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: ldfld ""object C.<N1>k__BackingField""
IL_000d: stfld ""object C.<N1>k__BackingField""
IL_0012: ldarg.0
IL_0013: ldarg.1
IL_0014: ldfld ""object C.<N2>k__BackingField""
IL_0019: stfld ""object C.<N2>k__BackingField""
IL_001e: ldarg.0
IL_001f: ldarg.1
IL_0020: ldfld ""int C.field""
IL_0025: stfld ""int C.field""
IL_002a: ldarg.0
IL_002b: ldarg.1
IL_002c: ldfld ""int C.Property""
IL_0031: stfld ""int C.Property""
IL_0036: ret
}");
}";
var comp = CreateCompilation(new[] { sourceA, sourceB });
comp.VerifyDiagnostics(
// (1,17): error CS8866: Record member 'A.P1' must be a readable instance property of type 'object' to match positional parameter 'P1'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P1").WithArguments("A.P1", "object", "P1").WithLocation(1, 17),
// (1,28): error CS8866: Record member 'A.P2' must be a readable instance property of type 'object' to match positional parameter 'P2'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P2").WithArguments("A.P2", "object", "P2").WithLocation(1, 28),
// (1,39): error CS8866: Record member 'A.P3' must be a readable instance property of type 'object' to match positional parameter 'P3'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P3").WithArguments("A.P3", "object", "P3").WithLocation(1, 39));
var actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.P4 { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
comp = CreateCompilation(sourceA);
var refA = comp.EmitToImageReference();
comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (1,17): error CS8866: Record member 'A.P1' must be a readable instance property of type 'object' to match positional parameter 'P1'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P1").WithArguments("A.P1", "object", "P1").WithLocation(1, 17),
// (1,39): error CS8866: Record member 'A.P3' must be a readable instance property of type 'object' to match positional parameter 'P3'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P3").WithArguments("A.P3", "object", "P3").WithLocation(1, 39));
actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.P2 { get; init; }",
"System.Object B.P4 { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor()
[Fact]
public void Inheritance_26()
{
var source =
@"public record B(object N1, object N2)
var sourceA =
@"public record A
{
}
public record C(object P1, object P2) : B(0, 1)
internal const int P = 4;
}";
var sourceB =
@"record B(object P) : A
{
public C(C c) // 1, 2
{
}
}
";
var comp = CreateCompilation(source);
}";
var comp = CreateCompilation(new[] { sourceA, sourceB });
comp.VerifyDiagnostics(
// (6,12): error CS1729: 'B' does not contain a constructor that takes 0 arguments
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "C").WithArguments("B", "0").WithLocation(6, 12),
// (6,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(6, 12)
);
// (1,17): error CS8866: Record member 'A.P' must be a readable instance property of type 'object' to match positional parameter 'P'.
// record B(object P) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P").WithArguments("A.P", "object", "P").WithLocation(1, 17));
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
comp = CreateCompilation(sourceA);
var refA = comp.EmitToImageReference();
comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }", "System.Object B.P { get; init; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject()
[Fact]
public void Inheritance_27()
{
var source =
@"public record C(int I)
@"record A
{
public int I { get; set; } = 42;
public C(C c)
{
}
public static void Main()
{
var c = new C(1);
c.I = 2;
var c2 = new C(c);
System.Console.Write((c.I, c2.I));
}
public object P { get; }
public object Q { get; set; }
}
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(2, 0)");
verifier.VerifyIL("C..ctor(C)", @"
record B(object get_P, object set_Q) : A
{
// Code size 9 (0x9)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ret
}
");
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.get_P { get; init; }",
"System.Object B.set_Q { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject_WithFieldInitializer()
[Fact]
public void Inheritance_28()
{
var source =
@"public record C(int I)
@"interface I
{
public int I { get; set; } = 42;
public int field = 43;
public C(C c)
{
System.Console.Write("" RAN "");
}
public static void Main()
{
var c = new C(1);
c.I = 2;
c.field = 100;
System.Console.Write((c.I, c.field));
var c2 = new C(c);
System.Console.Write((c2.I, c2.field));
}
object P { get; }
}
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(2, 100) RAN (0, 0)");
verifier.VerifyIL("C..ctor(C)", @"
record A : I
{
// Code size 20 (0x14)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ldstr "" RAN ""
IL_000d: call ""void System.Console.Write(string)""
IL_0012: nop
IL_0013: ret
object I.P => null;
}
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_DerivesFromObject_GivesParameterToBase()
{
var source = @"
public record C(object I)
record B(object P) : A
{
public C(C c) : base(1) { }
}
";
record C(object P) : I
{
object I.P => null;
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,21): error CS1729: 'object' does not contain a constructor that takes 1 arguments
// public C(C c) : base(1) { }
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "base").WithArguments("object", "1").WithLocation(4, 21),
// (4,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : base(1) { }
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(4, 21)
);
comp.VerifyDiagnostics();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }", "System.Object B.P { get; init; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }", "System.Object C.P { get; init; }", "System.Object C.I.P { get; }" }, GetProperties(comp, "C").ToTestDisplayStrings());
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_DerivesFromObject_WithSomeOtherConstructor()
[Fact]
public void Inheritance_29()
{
var source = @"
public record C(object I)
{
public C(int i) : this((object)null) { }
public static void Main()
{
var c = new C((object)null);
var c2 = new C(1);
var c3 = new C(c);
System.Console.Write(""RAN"");
}
}
var sourceA =
@"Public Class A
Public Property P(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Property Q(x As Object, y As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
End Class
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "RAN", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(int)", @"
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var sourceB =
@"record B(object P, object Q) : A
{
// Code size 10 (0xa)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: call ""C..ctor(object)""
IL_0007: nop
IL_0008: nop
IL_0009: ret
}
");
object P { get; }
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,8): error CS8867: No accessible copy constructor found in base type 'A'.
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "B").WithArguments("A").WithLocation(1, 8),
// (1,32): error CS8864: Records may only inherit from object or another record
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_BadRecordBase, "A").WithLocation(1, 32)
);
var actualMembers = GetProperties(compB, "B").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.Q { get; init; }",
"System.Object B.P { get; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject_UsesThis()
[Fact]
public void Inheritance_30()
{
var source =
@"public record C(int I)
{
public C(C c) : this(c.I)
{
}
}
var sourceA =
@"Public Class A
Public ReadOnly Overloads Property P() As Object
Get
Return Nothing
End Get
End Property
Public ReadOnly Overloads Property P(o As Object) As Object
Get
Return Nothing
End Get
End Property
Public Overloads Property Q(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Overloads Property Q() As Object
Get
Return Nothing
End Get
Set
End Set
End Property
End Class
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (3,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : this(c.I)
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "this").WithLocation(3, 21)
);
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var sourceB =
@"record B(object P, object Q) : A
{
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,8): error CS8867: No accessible copy constructor found in base type 'A'.
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "B").WithArguments("A").WithLocation(1, 8),
// (1,32): error CS8864: Records may only inherit from object or another record
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_BadRecordBase, "A").WithLocation(1, 32)
);
var actualMembers = GetProperties(compB, "B").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }" }, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefined_DerivesFromObject_UsesBase()
[Fact]
public void Inheritance_31()
{
var source =
@"public record C(int I)
{
public C(C c) : base()
{
System.Console.Write(""RAN "");
}
public static void Main()
{
var c = new C(1);
System.Console.Write(c.I);
System.Console.Write("" "");
var c2 = c with { I = 2 };
System.Console.Write(c2.I);
}
}
var sourceA =
@"Public Class A
Public ReadOnly Property P() As Object
Get
Return Nothing
End Get
End Property
Public Property Q(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Property R(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Sub New(a as A)
End Sub
End Class
Public Class B
Inherits A
Public ReadOnly Overloads Property P(o As Object) As Object
Get
Return Nothing
End Get
End Property
Public Overloads Property Q() As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Overloads Property R(x As Object, y As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Sub New(b as B)
MyBase.New(b)
End Sub
End Class
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "1 RAN 2", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var sourceB =
@"record C(object P, object Q, object R) : B
{
// Code size 20 (0x14)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ldstr ""RAN ""
IL_000d: call ""void System.Console.Write(string)""
IL_0012: nop
IL_0013: ret
}
");
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,9): error CS7036: There is no argument given that corresponds to the required formal parameter 'b' of 'B.B(B)'
// record C(object P, object Q, object R) : B
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "(object P, object Q, object R)").WithArguments("b", "B.B(B)").WithLocation(1, 9),
// (1,42): error CS8864: Records may only inherit from object or another record
// record C(object P, object Q, object R) : B
Diagnostic(ErrorCode.ERR_BadRecordBase, "B").WithLocation(1, 42)
);
var actualMembers = GetProperties(compB, "C").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type C.EqualityContract { get; }",
"System.Object C.R { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_NoPositionalMembers()
[Theory, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[InlineData(false)]
[InlineData(true)]
public void CopyCtor(bool useCompilationReference)
{
var source =
var sourceA =
@"public record B(object N1, object N2)
{
}
public record C(object P1) : B(0, 1)
{
public C(C c) // 1, 2
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (6,12): error CS1729: 'B' does not contain a constructor that takes 0 arguments
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "C").WithArguments("B", "0").WithLocation(6, 12),
// (6,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(6, 12)
);
}
}";
var compA = CreateCompilation(sourceA);
var verifierA = CompileAndVerify(compA, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_UsesThis()
{
var source =
@"public record B(object N1, object N2)
verifierA.VerifyIL("B..ctor(B)", @"
{
}
public record C(object P1, object P2) : B(0, 1)
// Code size 31 (0x1f)
.maxstack 2
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: ldfld ""object B.<N1>k__BackingField""
IL_000d: stfld ""object B.<N1>k__BackingField""
IL_0012: ldarg.0
IL_0013: ldarg.1
IL_0014: ldfld ""object B.<N2>k__BackingField""
IL_0019: stfld ""object B.<N2>k__BackingField""
IL_001e: ret
}");
var refA = useCompilationReference ? compA.ToMetadataReference() : compA.EmitToImageReference();
var sourceB =
@"record C(object P1, object P2) : B(3, 4)
{
public C(C c) : this(1, 2) // 1
static void Main()
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (6,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : this(1, 2) // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "this").WithLocation(6, 21)
);
var c1 = new C(1, 2);
System.Console.Write((c1.P1, c1.P2, c1.N1, c1.N2));
System.Console.Write("" "");
var c2 = new C(c1);
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2));
System.Console.Write("" "");
var c3 = c1 with { P1 = 10, N1 = 30 };
System.Console.Write((c3.P1, c3.P2, c3.N1, c3.N2));
}
}";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
compB.VerifyDiagnostics();
var verifierB = CompileAndVerify(compB, expectedOutput: "(1, 2, 3, 4) (1, 2, 3, 4) (10, 2, 30, 4)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
// call base copy constructor B..ctor(B)
verifierB.VerifyIL("C..ctor(C)", @"
{
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_UsesBase()
public void CopyCtor_WithOtherOverload()
{
var source =
@"public record B(int i)
@"public record B(object N1, object N2)
{
public B(C c) : this(30, 40) => throw null;
}
public record C(int j) : B(0)
public record C(object P1, object P2) : B(3, 4)
{
public C(C c) : base(1) // 1
static void Main()
{
var c1 = new C(1, 2);
System.Console.Write((c1.P1, c1.P2, c1.N1, c1.N2));
System.Console.Write("" "");
var c2 = c1 with { P1 = 10, P2 = 20, N1 = 30, N2 = 40 };
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2));
}
}
#nullable enable
public record D(int j) : B(0)
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 3, 4) (10, 20, 30, 40)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
// call base copy constructor B..ctor(B)
verifier.VerifyIL("C..ctor(C)", @"
{
public D(D? d) : base(1) // 2
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (6,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : base(1) // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(6, 21),
// (13,22): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public D(D? d) : base(1) // 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(13, 22)
);
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefined_WithFieldInitializers()
public void CopyCtor_WithObsoleteCopyConstructor()
{
var source =
@"public record C(int I)
@"public record B(object N1, object N2)
{
[System.Obsolete(""Obsolete"", true)]
public B(B b) { }
}
public record D(int J) : C(1)
{
public int field = 42;
public D(D d) : base(d)
{
System.Console.Write(""RAN "");
}
public static void Main()
{
var d = new D(2);
System.Console.Write((d.I, d.J, d.field));
System.Console.Write("" "");
public record C(object P1, object P2) : B(3, 4) { }
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
}
var d2 = d with { I = 10, J = 20 };
System.Console.Write((d2.I, d2.J, d.field));
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithParamsCopyConstructor()
{
var source =
@"public record B(object N1, object N2)
{
public B(B b, params int[] i) : this(30, 40) { }
}
public record C(object P1, object P2) : B(3, 4) { }
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 42) RAN (10, 20, 42)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("D..ctor(D)", @"
var actualMembers = comp.GetMember<NamedTypeSymbol>("B").GetMembers().Where(m => m.Name == ".ctor").ToTestDisplayStrings();
var expectedMembers = new[]
{
"B..ctor(System.Object N1, System.Object N2)",
"B..ctor(B b, params System.Int32[] i)",
"B..ctor(B )"
};
AssertEx.Equal(expectedMembers, actualMembers);
var verifier = CompileAndVerify(comp, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 21 (0x15)
// Code size 32 (0x20)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""C..ctor(C)""
IL_0007: nop
IL_0008: nop
IL_0009: ldstr ""RAN ""
IL_000e: call ""void System.Console.Write(string)""
IL_0013: nop
IL_0014: ret
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ret
}
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_Synthesized_WithFieldInitializers()
public void CopyCtor_WithInitializers()
{
var source =
@"public record C(int I)
{
}
public record D(int J) : C(1)
@"public record C(object N1, object N2)
{
public int field = 42;
public static void Main()
{
var d = new D(2);
System.Console.Write((d.I, d.J, d.field));
System.Console.Write("" "");
var d2 = d with { I = 10, J = 20 };
System.Console.Write((d2.I, d2.J, d.field));
}
}
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
private int field = 42;
public int Property = 43;
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 42) (10, 20, 42)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("D..ctor(D)", @"
{
// Code size 33 (0x21)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""C..ctor(C)""
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: ldfld ""int D.<J>k__BackingField""
IL_000f: stfld ""int D.<J>k__BackingField""
IL_0014: ldarg.0
IL_0015: ldarg.1
IL_0016: ldfld ""int D.field""
IL_001b: stfld ""int D.field""
IL_0020: ret
}
");
var verifier = CompileAndVerify(comp, verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 55 (0x37)
.maxstack 2
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: ldfld ""object C.<N1>k__BackingField""
IL_000d: stfld ""object C.<N1>k__BackingField""
IL_0012: ldarg.0
IL_0013: ldarg.1
IL_0014: ldfld ""object C.<N2>k__BackingField""
IL_0019: stfld ""object C.<N2>k__BackingField""
IL_001e: ldarg.0
IL_001f: ldarg.1
IL_0020: ldfld ""int C.field""
IL_0025: stfld ""int C.field""
IL_002a: ldarg.0
IL_002b: ldarg.1
IL_002c: ldfld ""int C.Property""
IL_0031: stfld ""int C.Property""
IL_0036: ret
}");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButPrivate()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor()
{
var source =
@"public record B(object N1, object N2)
{
private B(B b) { }
}
public record C(object P1, object P2) : B(0, 1)
{
private C(C c) : base(2, 3) { } // 1
}
public record D(object P1, object P2) : B(0, 1)
{
private D(D d) : base(d) { } // 2
public C(C c) // 1, 2
{
}
}
public record E(object P1, object P2) : B(0, 1); // 3
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (7,22): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// private C(C c) : base(2, 3) { } // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(7, 22),
// (11,22): error CS0122: 'B.B(B)' is inaccessible due to its protection level
// private D(D d) : base(d) { } // 2
Diagnostic(ErrorCode.ERR_BadAccess, "base").WithArguments("B.B(B)").WithLocation(11, 22),
// (13,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record E(object P1, object P2) : B(0, 1); // 3
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "E").WithArguments("B").WithLocation(13, 15)
// (6,12): error CS1729: 'B' does not contain a constructor that takes 0 arguments
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "C").WithArguments("B", "0").WithLocation(6, 12),
// (6,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(6, 12)
);
// Should we complain about private user-defined copy constructor on unsealed type (ie. will prevent inheritance)?
// https://github.com/dotnet/roslyn/issues/45012
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleToCallerFromPE()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject()
{
var sourceA =
@"public record B(object N1, object N2)
var source =
@"public record C(int I)
{
internal B(B b) { }
}";
var compA = CreateCompilation(sourceA);
var refA = compA.EmitToImageReference();
var sourceB = @"
record C(object P1, object P2) : B(3, 4); // 1
public int I { get; set; } = 42;
public C(C c)
{
}
public static void Main()
{
var c = new C(1);
c.I = 2;
var c2 = new C(c);
System.Console.Write((c.I, c2.I));
}
}
";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (2,8): error CS8867: No accessible copy constructor found in base type 'B'.
// record C(object P1, object P2) : B(3, 4); // 1
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 8)
);
var sourceC = @"
record C(object P1, object P2) : B(3, 4)
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(2, 0)");
verifier.VerifyIL("C..ctor(C)", @"
{
protected C(C c) : base(c) { } // 1, 2
// Code size 9 (0x9)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ret
}
";
var compC = CreateCompilation(sourceC, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compC.VerifyDiagnostics(
// (4,24): error CS7036: There is no argument given that corresponds to the required formal parameter 'N2' of 'B.B(object, object)'
// protected C(C c) : base(c) { } // 1, 2
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "base").WithArguments("N2", "B.B(object, object)").WithLocation(4, 24),
// (4,24): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// protected C(C c) : base(c) { } // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(4, 24)
);
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleToCallerFromPE_WithIVT()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject_WithFieldInitializer()
{
var sourceA = @"
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(""AssemblyB"")]
public record B(object N1, object N2)
var source =
@"public record C(int I)
{
internal B(B b) { }
}";
var compA = CreateCompilation(new[] { sourceA, IsExternalInitTypeDefinition }, assemblyName: "AssemblyA", parseOptions: TestOptions.RegularPreview);
var refA = compA.EmitToImageReference();
public int I { get; set; } = 42;
public int field = 43;
public C(C c)
{
System.Console.Write("" RAN "");
}
public static void Main()
{
var c = new C(1);
c.I = 2;
c.field = 100;
System.Console.Write((c.I, c.field));
var sourceB = @"
record C(int j) : B(3, 4);
var c2 = new C(c);
System.Console.Write((c2.I, c2.field));
}
}
";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, assemblyName: "AssemblyB");
compB.VerifyDiagnostics();
var sourceC = @"
record C(int j) : B(3, 4)
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(2, 100) RAN (0, 0)");
verifier.VerifyIL("C..ctor(C)", @"
{
protected C(C c) : base(c) { }
// Code size 20 (0x14)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ldstr "" RAN ""
IL_000d: call ""void System.Console.Write(string)""
IL_0012: nop
IL_0013: ret
}
";
var compC = CreateCompilation(sourceC, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, assemblyName: "AssemblyB");
compC.VerifyDiagnostics();
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[WorkItem(45012, "https://github.com/dotnet/roslyn/issues/45012")]
public void CopyCtor_UserDefinedButPrivate_InSealedType()
public void CopyCtor_DerivesFromObject_GivesParameterToBase()
{
var source =
@"public record B(int i)
{
}
public sealed record C(int j) : B(0)
var source = @"
public record C(object I)
{
private C(C c) : base(c)
{
}
public C(C c) : base(1) { }
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var copyCtor = comp.GetMembers("C..ctor")[0];
Assert.Equal("C..ctor(C c)", copyCtor.ToTestDisplayString());
Assert.True(copyCtor.DeclaredAccessibility == Accessibility.Private);
comp.VerifyDiagnostics(
// (4,21): error CS1729: 'object' does not contain a constructor that takes 1 arguments
// public C(C c) : base(1) { }
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "base").WithArguments("object", "1").WithLocation(4, 21),
// (4,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : base(1) { }
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(4, 21)
);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[WorkItem(45012, "https://github.com/dotnet/roslyn/issues/45012")]
public void CopyCtor_UserDefinedButInternal()
public void CopyCtor_DerivesFromObject_WithSomeOtherConstructor()
{
var source =
@"public record B(object N1, object N2)
{
}
public sealed record Sealed(object P1, object P2) : B(0, 1)
{
internal Sealed(Sealed s) : base(s)
{
}
}
public record Unsealed(object P1, object P2) : B(0, 1)
var source = @"
public record C(object I)
{
internal Unsealed(Unsealed s) : base(s)
public C(int i) : this((object)null) { }
public static void Main()
{
var c = new C((object)null);
var c2 = new C(1);
var c3 = new C(c);
System.Console.Write(""RAN"");
}
}
";
var comp = CreateCompilation(source);
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var sealedCopyCtor = comp.GetMembers("Sealed..ctor")[0];
Assert.Equal("Sealed..ctor(Sealed s)", sealedCopyCtor.ToTestDisplayString());
Assert.True(sealedCopyCtor.DeclaredAccessibility == Accessibility.Internal);
var unsealedCopyCtor = comp.GetMembers("Unsealed..ctor")[0];
Assert.Equal("Unsealed..ctor(Unsealed s)", unsealedCopyCtor.ToTestDisplayString());
Assert.True(unsealedCopyCtor.DeclaredAccessibility == Accessibility.Internal);
var verifier = CompileAndVerify(comp, expectedOutput: "RAN", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(int)", @"
{
// Code size 10 (0xa)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldnull
IL_0002: call ""C..ctor(object)""
IL_0007: nop
IL_0008: nop
IL_0009: ret
}
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_BaseHasRefKind()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_DerivesFromObject_UsesThis()
{
var source =
@"public record B(int i)
{
public B(ref B b) => throw null; // 1, not recognized as copy constructor
}
public record C(int j) : B(1)
@"public record C(int I)
{
internal C(C c) : base(c)
public C(C c) : this(c.I)
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (3,12): error CS8862: A constructor declared in a record with parameters must have 'this' constructor initializer.
// public B(ref B b) => throw null; // 1, not recognized as copy constructor
Diagnostic(ErrorCode.ERR_UnexpectedOrMissingConstructorInitializerInRecord, "B").WithLocation(3, 12)
// (3,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : this(c.I)
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "this").WithLocation(3, 21)
);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_BaseHasRefKind_WithThisInitializer()
public void CopyCtor_UserDefined_DerivesFromObject_UsesBase()
{
var source =
@"public record B(int i)
{
public B(ref B b) : this(0) => throw null; // 1, not recognized as copy constructor
}
public record C(int j) : B(1)
@"public record C(int I)
{
internal C(C c) : base(c)
public C(C c) : base()
{
System.Console.Write(""RAN "");
}
public static void Main()
{
var c = new C(1);
System.Console.Write(c.I);
System.Console.Write("" "");
var c2 = c with { I = 2 };
System.Console.Write(c2.I);
}
}
";
var comp = CreateCompilation(source);
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var actualMembers = comp.GetMember<NamedTypeSymbol>("B").GetMembers().Where(m => m.Name == ".ctor").ToTestDisplayStrings();
var expectedMembers = new[]
{
"B..ctor(System.Int32 i)",
"B..ctor(ref B b)",
"B..ctor(B )"
};
AssertEx.Equal(expectedMembers, actualMembers);
var verifier = CompileAndVerify(comp, expectedOutput: "1 RAN 2", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 20 (0x14)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: nop
IL_0007: nop
IL_0008: ldstr ""RAN ""
IL_000d: call ""void System.Console.Write(string)""
IL_0012: nop
IL_0013: ret
}
");
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithPrivateField()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_NoPositionalMembers()
{
var source =
@"public record B(object N1, object N2)
{
private int field1 = 100;
public int GetField1() => field1;
}
public record C(object P1, object P2) : B(3, 4)
public record C(object P1) : B(0, 1)
{
private int field2 = 200;
public int GetField2() => field2;
static void Main()
public C(C c) // 1, 2
{
var c1 = new C(1, 2);
var c2 = new C(c1);
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2, c2.GetField1(), c2.GetField2()));
}
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 3, 4, 100, 200)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 44 (0x2c)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ldarg.0
IL_0020: ldarg.1
IL_0021: ldfld ""int C.field2""
IL_0026: stfld ""int C.field2""
IL_002b: ret
}");
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (6,12): error CS1729: 'B' does not contain a constructor that takes 0 arguments
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "C").WithArguments("B", "0").WithLocation(6, 12),
// (6,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(6, 12)
);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_MissingInMetadata()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_UsesThis()
{
// IL for `public record B { }`
var ilSource = @"
.class public auto ansi beforefieldinit B extends [mscorlib]System.Object
var source =
@"public record B(object N1, object N2)
{
.method public hidebysig specialname newslot virtual instance class B '<>Clone' () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method family hidebysig newslot virtual instance class [mscorlib]System.Type get_EqualityContract () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance int32 GetHashCode () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance bool Equals ( object '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public newslot virtual instance bool Equals ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
// Removed copy constructor
//.method public hidebysig specialname rtspecialname instance void .ctor ( class B '' ) cil managed
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.property instance class [mscorlib]System.Type EqualityContract()
}
public record C(object P1, object P2) : B(0, 1)
{
public C(C c) : this(1, 2) // 1
{
.get instance class [mscorlib]System.Type B::get_EqualityContract()
}
}
";
var source = @"
public record C : B {
}";
var comp = CreateCompilationWithIL(new[] { source, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (2,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record C : B {
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 15)
);
var source2 = @"
public record C : B
{
public C(C c) { }
}";
var comp2 = CreateCompilationWithIL(new[] { source2, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp2.VerifyDiagnostics(
// (4,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) { }
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(4, 12)
// (6,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : this(1, 2) // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "this").WithLocation(6, 21)
);
}
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleInMetadata()
public void CopyCtor_UserDefinedButDoesNotDelegateToBaseCopyCtor_UsesBase()
{
// IL for `public record B { }`
var ilSource = @"
.class public auto ansi beforefieldinit B extends [mscorlib]System.Object
var source =
@"public record B(int i)
{
.method public hidebysig specialname newslot virtual instance class B '<>Clone' () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method family hidebysig newslot virtual instance class [mscorlib]System.Type get_EqualityContract () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance int32 GetHashCode () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance bool Equals ( object '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public newslot virtual instance bool Equals ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
// Inaccessible copy constructor
.method private hidebysig specialname rtspecialname instance void .ctor ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
}
public record C(int j) : B(0)
{
public C(C c) : base(1) // 1
{
IL_0000: ldnull
IL_0001: throw
}
.property instance class [mscorlib]System.Type EqualityContract()
}
#nullable enable
public record D(int j) : B(0)
{
public D(D? d) : base(1) // 2
{
.get instance class [mscorlib]System.Type B::get_EqualityContract()
}
}
";
var source = @"
public record C : B {
}";
var comp = CreateCompilationWithIL(new[] { source, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (2,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record C : B {
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 15)
// (6,21): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) : base(1) // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(6, 21),
// (13,22): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public D(D? d) : base(1) // 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(13, 22)
);
}
[Fact]
public void Inheritance_22()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefined_WithFieldInitializers()
{
var source =
@"record A
@"public record C(int I)
{
public ref object P1 => throw null;
public object P2 => throw null;
}
record B : A
public record D(int J) : C(1)
{
public new object P1 => throw null;
public new ref object P2 => throw null;
public int field = 42;
public D(D d) : base(d)
{
System.Console.Write(""RAN "");
}
public static void Main()
{
var d = new D(2);
System.Console.Write((d.I, d.J, d.field));
System.Console.Write("" "");
var d2 = d with { I = 10, J = 20 };
System.Console.Write((d2.I, d2.J, d.field));
}
}
record C(object P1, object P2) : B
{
}";
var comp = CreateCompilation(source);
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(comp, "C").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers);
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 42) RAN (10, 20, 42)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("D..ctor(D)", @"
{
// Code size 21 (0x15)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""C..ctor(C)""
IL_0007: nop
IL_0008: nop
IL_0009: ldstr ""RAN ""
IL_000e: call ""void System.Console.Write(string)""
IL_0013: nop
IL_0014: ret
}
");
}
[Fact]
public void Inheritance_23()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_Synthesized_WithFieldInitializers()
{
var source =
@"record A
@"public record C(int I)
{
public static object P1 { get; }
public object P2 { get; }
}
record B : A
public record D(int J) : C(1)
{
public new object P1 { get; }
public new static object P2 { get; }
public int field = 42;
public static void Main()
{
var d = new D(2);
System.Console.Write((d.I, d.J, d.field));
System.Console.Write("" "");
var d2 = d with { I = 10, J = 20 };
System.Console.Write((d2.I, d2.J, d.field));
}
}
record C(object P1, object P2) : B
{
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (11,28): error CS8866: Record member 'B.P2' must be a readable instance property of type 'object' to match positional parameter 'P2'.
// record C(object P1, object P2) : B
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P2").WithArguments("B.P2", "object", "P2").WithLocation(11, 28));
var actualMembers = GetProperties(comp, "C").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }" }, actualMembers);
";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 42) (10, 20, 42)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("D..ctor(D)", @"
{
// Code size 33 (0x21)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""C..ctor(C)""
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: ldfld ""int D.<J>k__BackingField""
IL_000f: stfld ""int D.<J>k__BackingField""
IL_0014: ldarg.0
IL_0015: ldarg.1
IL_0016: ldfld ""int D.field""
IL_001b: stfld ""int D.field""
IL_0020: ret
}
");
}
[Fact]
public void Inheritance_24()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_UserDefinedButPrivate()
{
var source =
@"record A
@"public record B(object N1, object N2)
{
public object get_P() => null;
public object set_Q() => null;
private B(B b) { }
}
record B(object P, object Q) : A
public record C(object P1, object P2) : B(0, 1)
{
private C(C c) : base(2, 3) { } // 1
}
record C(object P)
public record D(object P1, object P2) : B(0, 1)
{
public object get_P() => null;
public object set_Q() => null;
}";
private D(D d) : base(d) { } // 2
}
public record E(object P1, object P2) : B(0, 1); // 3
";
var comp = CreateCompilation(source);
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));
var expectedMembers = new[]
{
"A B.<>Clone()",
"System.Type B.EqualityContract.get",
"System.Type B.EqualityContract { get; }",
"B..ctor(System.Object P, System.Object Q)",
"System.Object B.<P>k__BackingField",
"System.Object B.P.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) B.P.init",
"System.Object B.P { get; init; }",
"System.Object B.<Q>k__BackingField",
"System.Object B.Q.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) B.Q.init",
"System.Object B.Q { get; init; }",
"System.Int32 B.GetHashCode()",
"System.Boolean B.Equals(System.Object? )",
"System.Boolean B.Equals(A? )",
"System.Boolean B.Equals(B? )",
"B..ctor(B )",
"void B.Deconstruct(out System.Object P, out System.Object Q)"
};
AssertEx.Equal(expectedMembers, comp.GetMember<NamedTypeSymbol>("B").GetMembers().ToTestDisplayStrings());
expectedMembers = new[]
{
"C C.<>Clone()",
"System.Type C.EqualityContract.get",
"System.Type C.EqualityContract { get; }",
"C..ctor(System.Object P)",
"System.Object C.<P>k__BackingField",
"System.Object C.P.get",
"void modreq(System.Runtime.CompilerServices.IsExternalInit) C.P.init",
"System.Object C.P { get; init; }",
"System.Object C.get_P()",
"System.Object C.set_Q()",
"System.Int32 C.GetHashCode()",
"System.Boolean C.Equals(System.Object? )",
"System.Boolean C.Equals(C? )",
"C..ctor(C )",
"void C.Deconstruct(out System.Object P)"
};
AssertEx.Equal(expectedMembers, comp.GetMember<NamedTypeSymbol>("C").GetMembers().ToTestDisplayStrings());
// (7,22): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// private C(C c) : base(2, 3) { } // 1
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(7, 22),
// (11,22): error CS0122: 'B.B(B)' is inaccessible due to its protection level
// private D(D d) : base(d) { } // 2
Diagnostic(ErrorCode.ERR_BadAccess, "base").WithArguments("B.B(B)").WithLocation(11, 22),
// (13,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record E(object P1, object P2) : B(0, 1); // 3
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "E").WithArguments("B").WithLocation(13, 15)
);
// Should we complain about private user-defined copy constructor on unsealed type (ie. will prevent inheritance)?
// https://github.com/dotnet/roslyn/issues/45012
}
[Fact]
public void Inheritance_25()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleToCallerFromPE()
{
var sourceA =
@"public record A
{
public class P1 { }
internal object P2 = 2;
public int P3(object o) => 3;
internal int P4<T>(T t) => 4;
}";
var sourceB =
@"record B(object P1, object P2, object P3, object P4) : A
@"public record B(object N1, object N2)
{
internal B(B b) { }
}";
var comp = CreateCompilation(new[] { sourceA, sourceB });
comp.VerifyDiagnostics(
// (1,17): error CS8866: Record member 'A.P1' must be a readable instance property of type 'object' to match positional parameter 'P1'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P1").WithArguments("A.P1", "object", "P1").WithLocation(1, 17),
// (1,28): error CS8866: Record member 'A.P2' must be a readable instance property of type 'object' to match positional parameter 'P2'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P2").WithArguments("A.P2", "object", "P2").WithLocation(1, 28),
// (1,39): error CS8866: Record member 'A.P3' must be a readable instance property of type 'object' to match positional parameter 'P3'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P3").WithArguments("A.P3", "object", "P3").WithLocation(1, 39));
var actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.P4 { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
var compA = CreateCompilation(sourceA);
var refA = compA.EmitToImageReference();
comp = CreateCompilation(sourceA);
var refA = comp.EmitToImageReference();
comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (1,17): error CS8866: Record member 'A.P1' must be a readable instance property of type 'object' to match positional parameter 'P1'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P1").WithArguments("A.P1", "object", "P1").WithLocation(1, 17),
// (1,39): error CS8866: Record member 'A.P3' must be a readable instance property of type 'object' to match positional parameter 'P3'.
// record B(object P1, object P2, object P3, object P4) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P3").WithArguments("A.P3", "object", "P3").WithLocation(1, 39));
actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.P2 { get; init; }",
"System.Object B.P4 { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
var sourceB = @"
record C(object P1, object P2) : B(3, 4); // 1
";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (2,8): error CS8867: No accessible copy constructor found in base type 'B'.
// record C(object P1, object P2) : B(3, 4); // 1
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 8)
);
var sourceC = @"
record C(object P1, object P2) : B(3, 4)
{
protected C(C c) : base(c) { } // 1, 2
}
";
var compC = CreateCompilation(sourceC, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compC.VerifyDiagnostics(
// (4,24): error CS7036: There is no argument given that corresponds to the required formal parameter 'N2' of 'B.B(object, object)'
// protected C(C c) : base(c) { } // 1, 2
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "base").WithArguments("N2", "B.B(object, object)").WithLocation(4, 24),
// (4,24): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// protected C(C c) : base(c) { } // 1, 2
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "base").WithLocation(4, 24)
);
}
[Fact]
public void Inheritance_26()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleToCallerFromPE_WithIVT()
{
var sourceA =
@"public record A
{
internal const int P = 4;
}";
var sourceB =
@"record B(object P) : A
var sourceA = @"
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(""AssemblyB"")]
public record B(object N1, object N2)
{
internal B(B b) { }
}";
var comp = CreateCompilation(new[] { sourceA, sourceB });
comp.VerifyDiagnostics(
// (1,17): error CS8866: Record member 'A.P' must be a readable instance property of type 'object' to match positional parameter 'P'.
// record B(object P) : A
Diagnostic(ErrorCode.ERR_BadRecordMemberForPositionalParameter, "P").WithArguments("A.P", "object", "P").WithLocation(1, 17));
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
var compA = CreateCompilation(new[] { sourceA, IsExternalInitTypeDefinition }, assemblyName: "AssemblyA", parseOptions: TestOptions.RegularPreview);
var refA = compA.EmitToImageReference();
comp = CreateCompilation(sourceA);
var refA = comp.EmitToImageReference();
comp = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }", "System.Object B.P { get; init; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
var sourceB = @"
record C(int j) : B(3, 4);
";
var compB = CreateCompilation(sourceB, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, assemblyName: "AssemblyB");
compB.VerifyDiagnostics();
var sourceC = @"
record C(int j) : B(3, 4)
{
protected C(C c) : base(c) { }
}
";
var compC = CreateCompilation(sourceC, references: new[] { refA }, parseOptions: TestOptions.RegularPreview, assemblyName: "AssemblyB");
compC.VerifyDiagnostics();
}
[Fact]
public void Inheritance_27()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[WorkItem(45012, "https://github.com/dotnet/roslyn/issues/45012")]
public void CopyCtor_UserDefinedButPrivate_InSealedType()
{
var source =
@"record A
@"public record B(int i)
{
public object P { get; }
public object Q { get; set; }
}
record B(object get_P, object set_Q) : A
public sealed record C(int j) : B(0)
{
}";
private C(C c) : base(c)
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(comp, "B").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.get_P { get; init; }",
"System.Object B.set_Q { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
var copyCtor = comp.GetMembers("C..ctor")[0];
Assert.Equal("C..ctor(C c)", copyCtor.ToTestDisplayString());
Assert.True(copyCtor.DeclaredAccessibility == Accessibility.Private);
}
[Fact]
public void Inheritance_28()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
[WorkItem(45012, "https://github.com/dotnet/roslyn/issues/45012")]
public void CopyCtor_UserDefinedButInternal()
{
var source =
@"interface I
@"public record B(object N1, object N2)
{
object P { get; }
}
record A : I
public sealed record Sealed(object P1, object P2) : B(0, 1)
{
object I.P => null;
internal Sealed(Sealed s) : base(s)
{
}
}
record B(object P) : A
public record Unsealed(object P1, object P2) : B(0, 1)
{
internal Unsealed(Unsealed s) : base(s)
{
}
}
record C(object P) : I
{
object I.P => null;
}";
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }", "System.Object B.P { get; init; }" }, GetProperties(comp, "B").ToTestDisplayStrings());
AssertEx.Equal(new[] { "System.Type C.EqualityContract { get; }", "System.Object C.P { get; init; }", "System.Object C.I.P { get; }" }, GetProperties(comp, "C").ToTestDisplayStrings());
var sealedCopyCtor = comp.GetMembers("Sealed..ctor")[0];
Assert.Equal("Sealed..ctor(Sealed s)", sealedCopyCtor.ToTestDisplayString());
Assert.True(sealedCopyCtor.DeclaredAccessibility == Accessibility.Internal);
var unsealedCopyCtor = comp.GetMembers("Unsealed..ctor")[0];
Assert.Equal("Unsealed..ctor(Unsealed s)", unsealedCopyCtor.ToTestDisplayString());
Assert.True(unsealedCopyCtor.DeclaredAccessibility == Accessibility.Internal);
}
[Fact]
public void Inheritance_29()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_BaseHasRefKind()
{
var sourceA =
@"Public Class A
Public Property P(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Property Q(x As Object, y As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
End Class
var source =
@"public record B(int i)
{
public B(ref B b) => throw null; // 1, not recognized as copy constructor
}
public record C(int j) : B(1)
{
internal C(C c) : base(c)
{
}
}
";
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (3,12): error CS8862: A constructor declared in a record with parameters must have 'this' constructor initializer.
// public B(ref B b) => throw null; // 1, not recognized as copy constructor
Diagnostic(ErrorCode.ERR_UnexpectedOrMissingConstructorInitializerInRecord, "B").WithLocation(3, 12)
);
}
var sourceB =
@"record B(object P, object Q) : A
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_BaseHasRefKind_WithThisInitializer()
{
var source =
@"public record B(int i)
{
object P { get; }
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,8): error CS8867: No accessible copy constructor found in base type 'A'.
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "B").WithArguments("A").WithLocation(1, 8),
// (1,32): error CS8864: Records may only inherit from object or another record
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_BadRecordBase, "A").WithLocation(1, 32)
);
public B(ref B b) : this(0) => throw null; // 1, not recognized as copy constructor
}
public record C(int j) : B(1)
{
internal C(C c) : base(c)
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(compB, "B").ToTestDisplayStrings();
var actualMembers = comp.GetMember<NamedTypeSymbol>("B").GetMembers().Where(m => m.Name == ".ctor").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type B.EqualityContract { get; }",
"System.Object B.Q { get; init; }",
"System.Object B.P { get; }",
"B..ctor(System.Int32 i)",
"B..ctor(ref B b)",
"B..ctor(B )"
};
AssertEx.Equal(expectedMembers, actualMembers);
}
[Fact]
public void Inheritance_30()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_WithPrivateField()
{
var sourceA =
@"Public Class A
Public ReadOnly Overloads Property P() As Object
Get
Return Nothing
End Get
End Property
Public ReadOnly Overloads Property P(o As Object) As Object
Get
Return Nothing
End Get
End Property
Public Overloads Property Q(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Overloads Property Q() As Object
Get
Return Nothing
End Get
Set
End Set
End Property
End Class
";
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var sourceB =
@"record B(object P, object Q) : A
var source =
@"public record B(object N1, object N2)
{
private int field1 = 100;
public int GetField1() => field1;
}
public record C(object P1, object P2) : B(3, 4)
{
private int field2 = 200;
public int GetField2() => field2;
static void Main()
{
var c1 = new C(1, 2);
var c2 = new C(c1);
System.Console.Write((c2.P1, c2.P2, c2.N1, c2.N2, c2.GetField1(), c2.GetField2()));
}
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,8): error CS8867: No accessible copy constructor found in base type 'A'.
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "B").WithArguments("A").WithLocation(1, 8),
// (1,32): error CS8864: Records may only inherit from object or another record
// record B(object P, object Q) : A
Diagnostic(ErrorCode.ERR_BadRecordBase, "A").WithLocation(1, 32)
);
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, parseOptions: TestOptions.RegularPreview, options: TestOptions.ReleaseExe);
comp.VerifyDiagnostics();
var actualMembers = GetProperties(compB, "B").ToTestDisplayStrings();
AssertEx.Equal(new[] { "System.Type B.EqualityContract { get; }" }, actualMembers);
var verifier = CompileAndVerify(comp, expectedOutput: "(1, 2, 3, 4, 100, 200)", verify: ExecutionConditionUtil.IsCoreClr ? Verification.Skipped : Verification.Fails);
verifier.VerifyIL("C..ctor(C)", @"
{
// Code size 44 (0x2c)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""B..ctor(B)""
IL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldfld ""object C.<P1>k__BackingField""
IL_000e: stfld ""object C.<P1>k__BackingField""
IL_0013: ldarg.0
IL_0014: ldarg.1
IL_0015: ldfld ""object C.<P2>k__BackingField""
IL_001a: stfld ""object C.<P2>k__BackingField""
IL_001f: ldarg.0
IL_0020: ldarg.1
IL_0021: ldfld ""int C.field2""
IL_0026: stfld ""int C.field2""
IL_002b: ret
}");
}
[Fact]
public void Inheritance_31()
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_MissingInMetadata()
{
var sourceA =
@"Public Class A
Public ReadOnly Property P() As Object
Get
Return Nothing
End Get
End Property
Public Property Q(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Property R(o As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Sub New(a as A)
End Sub
End Class
Public Class B
Inherits A
Public ReadOnly Overloads Property P(o As Object) As Object
Get
Return Nothing
End Get
End Property
Public Overloads Property Q() As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Overloads Property R(x As Object, y As Object) As Object
Get
Return Nothing
End Get
Set
End Set
End Property
Public Sub New(b as B)
MyBase.New(b)
End Sub
End Class
// IL for `public record B { }`
var ilSource = @"
.class public auto ansi beforefieldinit B extends [mscorlib]System.Object
{
.method public hidebysig specialname newslot virtual instance class B '<>Clone' () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method family hidebysig newslot virtual instance class [mscorlib]System.Type get_EqualityContract () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance int32 GetHashCode () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance bool Equals ( object '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public newslot virtual instance bool Equals ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
// Removed copy constructor
//.method public hidebysig specialname rtspecialname instance void .ctor ( class B '' ) cil managed
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.property instance class [mscorlib]System.Type EqualityContract()
{
.get instance class [mscorlib]System.Type B::get_EqualityContract()
}
}
";
var compA = CreateVisualBasicCompilation(sourceA);
compA.VerifyDiagnostics();
var refA = compA.EmitToImageReference();
var source = @"
public record C : B {
}";
var comp = CreateCompilationWithIL(new[] { source, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (2,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record C : B {
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 15)
);
var sourceB =
@"record C(object P, object Q, object R) : B
var source2 = @"
public record C : B
{
public C(C c) { }
}";
var compB = CreateCompilation(new[] { sourceB, IsExternalInitTypeDefinition }, references: new[] { refA }, parseOptions: TestOptions.RegularPreview);
compB.VerifyDiagnostics(
// (1,9): error CS7036: There is no argument given that corresponds to the required formal parameter 'b' of 'B.B(B)'
// record C(object P, object Q, object R) : B
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "(object P, object Q, object R)").WithArguments("b", "B.B(B)").WithLocation(1, 9),
// (1,42): error CS8864: Records may only inherit from object or another record
// record C(object P, object Q, object R) : B
Diagnostic(ErrorCode.ERR_BadRecordBase, "B").WithLocation(1, 42)
);
var comp2 = CreateCompilationWithIL(new[] { source2, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp2.VerifyDiagnostics(
// (4,12): error CS8868: A copy constructor in a record must call a copy constructor of the base, or a parameterless object constructor if the record inherits from object.
// public C(C c) { }
Diagnostic(ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor, "C").WithLocation(4, 12)
);
}
var actualMembers = GetProperties(compB, "C").ToTestDisplayStrings();
var expectedMembers = new[]
{
"System.Type C.EqualityContract { get; }",
"System.Object C.R { get; init; }",
};
AssertEx.Equal(expectedMembers, actualMembers);
[Fact, WorkItem(44902, "https://github.com/dotnet/roslyn/issues/44902")]
public void CopyCtor_InaccessibleInMetadata()
{
// IL for `public record B { }`
var ilSource = @"
.class public auto ansi beforefieldinit B extends [mscorlib]System.Object
{
.method public hidebysig specialname newslot virtual instance class B '<>Clone' () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method family hidebysig newslot virtual instance class [mscorlib]System.Type get_EqualityContract () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance int32 GetHashCode () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig virtual instance bool Equals ( object '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public newslot virtual instance bool Equals ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
// Inaccessible copy constructor
.method private hidebysig specialname rtspecialname instance void .ctor ( class B '' ) cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
{
IL_0000: ldnull
IL_0001: throw
}
.property instance class [mscorlib]System.Type EqualityContract()
{
.get instance class [mscorlib]System.Type B::get_EqualityContract()
}
}
";
var source = @"
public record C : B {
}";
var comp = CreateCompilationWithIL(new[] { source, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (2,15): error CS8867: No accessible copy constructor found in base type 'B'.
// public record C : B {
Diagnostic(ErrorCode.ERR_NoCopyConstructorInBaseType, "C").WithArguments("B").WithLocation(2, 15)
);
}
[Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册