From 6218c6adf0afebd54f73c936fe78fffcebff86d3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 29 Jul 2022 12:36:18 -0700 Subject: [PATCH 1/4] Auto-default ref fields with a null ref-assignment --- .../Portable/FlowAnalysis/FlowAnalysisPass.cs | 24 ++- .../LocalRewriter_FixedStatement.cs | 7 +- .../Lowering/SyntheticBoundNodeFactory.cs | 7 + .../Test/Semantic/Semantics/RefFieldTests.cs | 193 ++++++++++++++++++ .../Semantics/StructConstructorTests.cs | 40 ++++ 5 files changed, 260 insertions(+), 11 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/FlowAnalysisPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/FlowAnalysisPass.cs index 653f0b3d2e50c..1f2f312f6bd72 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/FlowAnalysisPass.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/FlowAnalysisPass.cs @@ -113,11 +113,25 @@ private static BoundBlock PrependImplicitInitializations(BoundBlock body, Method var builder = ArrayBuilder.GetInstance(implicitlyInitializedFields.Length); foreach (var field in implicitlyInitializedFields) { - builder.Add( - F.ExpressionStatement( - F.AssignmentExpression( - F.Field(F.This(), field), - F.Default(field.Type)))); + if (field.RefKind == RefKind.None) + { + // field = default(T); + builder.Add( + F.ExpressionStatement( + F.AssignmentExpression( + F.Field(F.This(), field), + F.Default(field.Type)))); + } + else + { + // field = ref *default(T*); + builder.Add( + F.ExpressionStatement( + F.AssignmentExpression( + F.Field(F.This(), field), + F.NullRef(field.TypeWithAnnotations), + isRef: true))); + } } var initializations = F.HiddenSequencePoint(F.Block(builder.ToImmutableAndFree())); diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs index 35f386c718a42..ed20771faf0c0 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs @@ -43,12 +43,7 @@ public override BoundNode VisitFixedStatement(BoundFixedStatement node) Debug.Assert(!pinnedTemp.Type.IsManagedTypeNoUseSiteDiagnostics); // temp = ref *default(T*); - cleanup[i] = _factory.Assignment(_factory.Local(pinnedTemp), new BoundPointerIndirectionOperator( - _factory.Syntax, - _factory.Default(new PointerTypeSymbol(pinnedTemp.TypeWithAnnotations)), - refersToLocation: false, - pinnedTemp.Type), - isRef: true); + cleanup[i] = _factory.Assignment(_factory.Local(pinnedTemp), _factory.NullRef(pinnedTemp.TypeWithAnnotations), isRef: true); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index 761d756887d6f..c5cb6b343c5b1 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -1137,6 +1137,13 @@ public BoundExpression Null(TypeSymbol type) return Null(type, Syntax); } + // Produce a ByRef null of given type, like `ref T Unsafe.NullRef()`. + public BoundExpression NullRef(TypeWithAnnotations type) + { + // *default(T*) + return new BoundPointerIndirectionOperator(Syntax, Default(new PointerTypeSymbol(type)), refersToLocation: false, type.Type); + } + public static BoundExpression Null(TypeSymbol type, SyntaxNode syntax) { Debug.Assert(type.CanBeAssignedNull()); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 92854472e3261..0dec463b3ec11 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -12592,5 +12592,198 @@ public void ScopedReserved_Alias_Escaped() Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) ); } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_UnsafeNullRef() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + + public R() + { + field = ref System.Runtime.CompilerServices.Unsafe.NullRef(); + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net60); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 22 (0x16) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: call ""ref int System.Runtime.CompilerServices.Unsafe.NullRef()"" + IL_0006: stfld ""ref int R.field"" + IL_000b: ldstr ""explicit ctor"" + IL_0010: call ""void System.Console.WriteLine(string)"" + IL_0015: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_RefReadonly() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref readonly int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics(); + + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref readonly int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_ReadonlyRef() + { + var source = """ +using System; + +var r = new R(); + +ref struct R +{ + public readonly ref int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0 + // public readonly ref int field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "0").WithLocation(7, 29) + ); + + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_WithOtherFieldInitializer() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + public int otherField = 42; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" + { + // Code size 27 (0x1b) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldarg.0 + IL_0009: ldc.i4.s 42 + IL_000b: stfld ""int R.otherField"" + IL_0010: ldstr ""explicit ctor"" + IL_0015: call ""void System.Console.WriteLine(string)"" + IL_001a: ret +}"); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StructConstructorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StructConstructorTests.cs index 4bee8eeeb96b4..6fd294b8f8934 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StructConstructorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StructConstructorTests.cs @@ -3929,6 +3929,46 @@ .maxstack 2 "); } + [Fact] + public void ImplicitlyInitializedField_Pointer() + { + var source = """ +using System; + +_ = new R(); + +unsafe struct R +{ + public int* field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe); + comp.VerifyDiagnostics( + // (7,17): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value + // public int* field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "").WithLocation(7, 17) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: "explicit ctor"); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 25 (0x19) + .maxstack 1 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldflda ""int* R.field"" + IL_0007: initobj ""int*"" + IL_000d: ldstr ""explicit ctor"" + IL_0012: call ""void System.Console.WriteLine(string)"" + IL_0017: nop + IL_0018: ret +}"); + } + [Fact] public void ImplicitlyInitializedField_NotOtherStruct() { From f9a37cb8a250860d5aa42dca5a531b7e7cf5abf7 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 29 Jul 2022 16:35:28 -0700 Subject: [PATCH 2/4] Move tests --- .../Test/Semantic/Semantics/RefFieldTests.cs | 428 +++++++++--------- 1 file changed, 214 insertions(+), 214 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 0dec463b3ec11..c319b53c2c03e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -538,6 +538,220 @@ ref struct R Diagnostic(ErrorCode.ERR_BadMemberFlag, "_v2").WithArguments("volatile").WithLocation(9, 31)); } + [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] + public void ScopedReserved_Alias_Escaped() + { + var source = """ +using @scoped = System.Int32; +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + + comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_UnsafeNullRef() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + + public R() + { + field = ref System.Runtime.CompilerServices.Unsafe.NullRef(); + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net60); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 22 (0x16) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: call ""ref int System.Runtime.CompilerServices.Unsafe.NullRef()"" + IL_0006: stfld ""ref int R.field"" + IL_000b: ldstr ""explicit ctor"" + IL_0010: call ""void System.Console.WriteLine(string)"" + IL_0015: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_RefReadonly() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref readonly int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics(); + + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref readonly int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_ReadonlyRef() + { + var source = """ +using System; + +var r = new R(); + +ref struct R +{ + public readonly ref int field; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0 + // public readonly ref int field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "0").WithLocation(7, 29) + ); + + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" +{ + // Code size 19 (0x13) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldstr ""explicit ctor"" + IL_000d: call ""void System.Console.WriteLine(string)"" + IL_0012: ret +}"); + } + + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + public void InitRefField_AutoDefault_WithOtherFieldInitializer() + { + var source = """ +using System; + +var x = 42; +scoped var r = new R(); +r.field = ref x; + +ref struct R +{ + public ref int field; + public int otherField = 42; + + public R() + { + Console.WriteLine("explicit ctor"); + } +} +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); + verifier.VerifyIL("R..ctor()", @" + { + // Code size 27 (0x1b) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: conv.u + IL_0003: stfld ""ref int R.field"" + IL_0008: ldarg.0 + IL_0009: ldc.i4.s 42 + IL_000b: stfld ""int R.otherField"" + IL_0010: ldstr ""explicit ctor"" + IL_0015: call ""void System.Console.WriteLine(string)"" + IL_001a: ret +}"); + } + /// /// Unexpected modreq(). /// @@ -12571,219 +12785,5 @@ public void ScopedReserved_Alias() Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 7) ); } - - [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] - public void ScopedReserved_Alias_Escaped() - { - var source = """ -using @scoped = System.Int32; -"""; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - } - - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] - public void InitRefField_AutoDefault() - { - var source = """ -using System; - -var x = 42; -scoped var r = new R(); -r.field = ref x; - -ref struct R -{ - public ref int field; - - public R() - { - Console.WriteLine("explicit ctor"); - } -} -"""; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); - verifier.VerifyIL("R..ctor()", @" -{ - // Code size 19 (0x13) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.0 - IL_0002: conv.u - IL_0003: stfld ""ref int R.field"" - IL_0008: ldstr ""explicit ctor"" - IL_000d: call ""void System.Console.WriteLine(string)"" - IL_0012: ret -}"); - } - - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] - public void InitRefField_UnsafeNullRef() - { - var source = """ -using System; - -var x = 42; -scoped var r = new R(); -r.field = ref x; - -ref struct R -{ - public ref int field; - - public R() - { - field = ref System.Runtime.CompilerServices.Unsafe.NullRef(); - Console.WriteLine("explicit ctor"); - } -} -"""; - var comp = CreateCompilation(source, targetFramework: TargetFramework.Net60); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); - verifier.VerifyIL("R..ctor()", @" -{ - // Code size 22 (0x16) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: call ""ref int System.Runtime.CompilerServices.Unsafe.NullRef()"" - IL_0006: stfld ""ref int R.field"" - IL_000b: ldstr ""explicit ctor"" - IL_0010: call ""void System.Console.WriteLine(string)"" - IL_0015: ret -}"); - } - - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] - public void InitRefField_AutoDefault_RefReadonly() - { - var source = """ -using System; - -var x = 42; -scoped var r = new R(); -r.field = ref x; - -ref struct R -{ - public ref readonly int field; - - public R() - { - Console.WriteLine("explicit ctor"); - } -} -"""; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics(); - - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); - verifier.VerifyIL("R..ctor()", @" -{ - // Code size 19 (0x13) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.0 - IL_0002: conv.u - IL_0003: stfld ""ref readonly int R.field"" - IL_0008: ldstr ""explicit ctor"" - IL_000d: call ""void System.Console.WriteLine(string)"" - IL_0012: ret -}"); - } - - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] - public void InitRefField_AutoDefault_ReadonlyRef() - { - var source = """ -using System; - -var r = new R(); - -ref struct R -{ - public readonly ref int field; - - public R() - { - Console.WriteLine("explicit ctor"); - } -} -"""; - var comp = CreateCompilation(source); - comp.VerifyDiagnostics( - // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0 - // public readonly ref int field; - Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "0").WithLocation(7, 29) - ); - - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); - verifier.VerifyIL("R..ctor()", @" -{ - // Code size 19 (0x13) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.0 - IL_0002: conv.u - IL_0003: stfld ""ref int R.field"" - IL_0008: ldstr ""explicit ctor"" - IL_000d: call ""void System.Console.WriteLine(string)"" - IL_0012: ret -}"); - } - - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] - public void InitRefField_AutoDefault_WithOtherFieldInitializer() - { - var source = """ -using System; - -var x = 42; -scoped var r = new R(); -r.field = ref x; - -ref struct R -{ - public ref int field; - public int otherField = 42; - - public R() - { - Console.WriteLine("explicit ctor"); - } -} -"""; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); - comp.VerifyDiagnostics(); - var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); - verifier.VerifyIL("R..ctor()", @" - { - // Code size 27 (0x1b) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.0 - IL_0002: conv.u - IL_0003: stfld ""ref int R.field"" - IL_0008: ldarg.0 - IL_0009: ldc.i4.s 42 - IL_000b: stfld ""int R.otherField"" - IL_0010: ldstr ""explicit ctor"" - IL_0015: call ""void System.Console.WriteLine(string)"" - IL_001a: ret -}"); - } } } From 80c85079bcffbb4577fcbedae9077b96b36d6838 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 5 Aug 2022 08:17:52 -0700 Subject: [PATCH 3/4] Resolve conflicts --- .../Test/Semantic/Semantics/RefFieldTests.cs | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index af9f34ee49cdf..1eb50b6047936 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -609,7 +609,7 @@ public R() } } """; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, runtimeFeature: RuntimeFlag.ByRefFields); comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); verifier.VerifyIL("R..ctor()", @" @@ -626,7 +626,8 @@ .maxstack 2 }"); } - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] + // Test skipped because we don't allow faking runtime feature flags when using specific TargetFramework + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/61463"), WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] public void InitRefField_UnsafeNullRef() { var source = """ @@ -683,7 +684,7 @@ public R() } } """; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, runtimeFeature: RuntimeFlag.ByRefFields); comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); @@ -719,7 +720,7 @@ public R() } } """; - var comp = CreateCompilation(source); + var comp = CreateCompilation(source, runtimeFeature: RuntimeFlag.ByRefFields); comp.VerifyDiagnostics( // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0 // public readonly ref int field; @@ -762,7 +763,7 @@ public R() } } """; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11, runtimeFeature: RuntimeFlag.ByRefFields); comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor")); verifier.VerifyIL("R..ctor()", @" @@ -12853,27 +12854,6 @@ public void ScopedReserved_Alias() ); } - [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] - public void ScopedReserved_Alias_Escaped() - { - var source = """ -using @scoped = System.Int32; -"""; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - } - [Theory] [InlineData("struct")] [InlineData("ref struct")] From 915ecd13c6c2f1f25b5682cbadc4a76912d831b0 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 5 Aug 2022 08:36:13 -0700 Subject: [PATCH 4/4] Move test back to original location --- .../Test/Semantic/Semantics/RefFieldTests.cs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 1eb50b6047936..7d7dfe8a31abd 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -568,27 +568,6 @@ ref struct R Diagnostic(ErrorCode.ERR_BadMemberFlag, "_v2").WithArguments("volatile").WithLocation(9, 31)); } - [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] - public void ScopedReserved_Alias_Escaped() - { - var source = """ -using @scoped = System.Int32; -"""; - var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - - comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); - comp.VerifyDiagnostics( - // (1,1): hidden CS8019: Unnecessary using directive. - // using @scoped = System.Int32; - Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) - ); - } - [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] public void InitRefField_AutoDefault() { @@ -12854,6 +12833,27 @@ public void ScopedReserved_Alias() ); } + [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] + public void ScopedReserved_Alias_Escaped() + { + var source = """ +using @scoped = System.Int32; +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + + comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + } + [Theory] [InlineData("struct")] [InlineData("ref struct")]