From 5ac052e6ac64aff6f5ea817d2a5e13685fa0446e Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 21 May 2024 21:47:37 -0700 Subject: [PATCH 1/7] Add baseline test for rewritting receiver which is a ref to a reference type --- .../Semantic/Semantics/InterpolationTests.cs | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index bc59532de1d2b..38dcc0729c2d3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -18539,5 +18539,173 @@ public static void M(ref A a) {} // public A(int x, A a = M($"{1}")) { } Diagnostic(ErrorCode.ERR_BadArgRef, @"$""{1}""").WithArguments("1", "ref").WithLocation(8, 29)); } + + [Theory] + [CombinatorialData] + public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver( + [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) + { + var code = $$""" +using System; +using System.Runtime.CompilerServices; +C c = new C(5); +ref C c2 = ref c; +C otherC = null; +c2.M({{expression}}, c2 = ref otherC); + +public class C +{ + public int Prop { get; } + public C(int i) => Prop = i; + public void M([InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c, C cNull) + { + Console.WriteLine(cNull is null); + Console.WriteLine(c.ToString()); + } +} + +public partial struct CustomHandler +{ + public CustomHandler(int literalLength, int formattedCount, C c) : this(literalLength, formattedCount) + { + _builder.AppendLine("c.Prop:" + c.Prop.ToString()); + } +} +"""; + + var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); + + var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }); + var verifier = CompileAndVerify(comp, expectedOutput: """ +True +c.Prop:5 +literal:literal +"""); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("", """ +{ + // Code size 53 (0x35) + .maxstack 5 + .locals init (C V_0, //c + C& V_1, //c2 + C V_2, //otherC + C& V_3, + CustomHandler V_4) + IL_0000: ldc.i4.5 + IL_0001: newobj "C..ctor(int)" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: stloc.1 + IL_000a: ldnull + IL_000b: stloc.2 + IL_000c: ldloc.1 + IL_000d: stloc.3 + IL_000e: ldloc.3 + IL_000f: ldind.ref + IL_0010: ldloca.s V_4 + IL_0012: ldc.i4.7 + IL_0013: ldc.i4.0 + IL_0014: ldloc.3 + IL_0015: ldind.ref + IL_0016: call "CustomHandler..ctor(int, int, C)" + IL_001b: ldloca.s V_4 + IL_001d: ldstr "literal" + IL_0022: call "bool CustomHandler.AppendLiteral(string)" + IL_0027: pop + IL_0028: ldloc.s V_4 + IL_002a: ldloca.s V_2 + IL_002c: dup + IL_002d: stloc.1 + IL_002e: ldind.ref + IL_002f: callvirt "void C.M(CustomHandler, C)" + IL_0034: ret +} +"""); + } + + [Theory] + [CombinatorialData] + public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver_ReverseOrder( + [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) + { + var code = $$""" +using System; +using System.Runtime.CompilerServices; +C c = new C(5); +ref C c2 = ref c; +C otherC = null; +c2.M(c2 = ref otherC, {{expression}}); + +public class C +{ + public int Prop { get; } + public C(int i) => Prop = i; + public void M(C cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c) + { + Console.WriteLine(cNull is null); + Console.WriteLine(c.ToString()); + } +} + +public partial struct CustomHandler +{ + public CustomHandler(int literalLength, int formattedCount, C c) : this(literalLength, formattedCount) + { + _builder.AppendLine("c.Prop:" + c.Prop.ToString()); + } +} +"""; + + var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); + + var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }); + var verifier = CompileAndVerify(comp, expectedOutput: """ +True +c.Prop:5 +literal:literal +"""); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("", """ +{ + // Code size 53 (0x35) + .maxstack 6 + .locals init (C V_0, //c + C& V_1, //c2 + C V_2, //otherC + C& V_3, + CustomHandler V_4) + IL_0000: ldc.i4.5 + IL_0001: newobj "C..ctor(int)" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: stloc.1 + IL_000a: ldnull + IL_000b: stloc.2 + IL_000c: ldloc.1 + IL_000d: stloc.3 + IL_000e: ldloc.3 + IL_000f: ldind.ref + IL_0010: ldloca.s V_2 + IL_0012: dup + IL_0013: stloc.1 + IL_0014: ldind.ref + IL_0015: ldloca.s V_4 + IL_0017: ldc.i4.7 + IL_0018: ldc.i4.0 + IL_0019: ldloc.3 + IL_001a: ldind.ref + IL_001b: call "CustomHandler..ctor(int, int, C)" + IL_0020: ldloca.s V_4 + IL_0022: ldstr "literal" + IL_0027: call "bool CustomHandler.AppendLiteral(string)" + IL_002c: pop + IL_002d: ldloc.s V_4 + IL_002f: callvirt "void C.M(C, CustomHandler)" + IL_0034: ret +} +"""); + } } } From 99e5c2fc28e3a6cbc746b0d8fe4ee1e5ed282dc1 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 21 May 2024 21:54:03 -0700 Subject: [PATCH 2/7] Always use a by-value temp to capture a reference type receiver --- .../LocalRewriter/LocalRewriter_Call.cs | 27 ++- .../Test/Emit2/CodeGen/CodeGenCallTests.cs | 50 +++-- .../Semantic/Semantics/InterpolationTests.cs | 180 +++++++++--------- .../RawInterpolationTests_Handler.cs | 84 ++++---- 4 files changed, 169 insertions(+), 172 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index bdddfdbab14ef..242a98b3ba65c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -677,17 +677,24 @@ private ImmutableArray VisitArgumentsAndCaptureReceiverIfNeeded } else { - refKind = rewrittenReceiver.GetRefKind(); - - if (refKind == RefKind.None && - !rewrittenReceiver.Type.IsReferenceType && - Binder.HasHome(rewrittenReceiver, - Binder.AddressKind.Constrained, - _factory.CurrentFunction, - peVerifyCompatEnabled: false, - stackLocalsOpt: null)) + if (rewrittenReceiver.Type.IsReferenceType) { - refKind = RefKind.Ref; + refKind = RefKind.None; + } + else + { + refKind = rewrittenReceiver.GetRefKind(); + + if (refKind == RefKind.None && + !rewrittenReceiver.Type.IsReferenceType && + Binder.HasHome(rewrittenReceiver, + Binder.AddressKind.Constrained, + _factory.CurrentFunction, + peVerifyCompatEnabled: false, + stackLocalsOpt: null)) + { + refKind = RefKind.Ref; + } } } diff --git a/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenCallTests.cs b/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenCallTests.cs index b44473ddc63a6..ea003bba0b2f6 100644 --- a/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenCallTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenCallTests.cs @@ -2137,36 +2137,32 @@ public DummyHandler(int literalLength, int formattedCount, IMoveable logger) verifier.VerifyIL("Program.Call1", @" { - // Code size 70 (0x46) + // Code size 61 (0x3d) .maxstack 6 - .locals init (T& V_0, - T V_1, - DummyHandler V_2) + .locals init (T V_0, + DummyHandler V_1) IL_0000: ldarg.0 IL_0001: ldobj ""T"" - IL_0006: stloc.1 - IL_0007: ldloca.s V_1 - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldarg.0 - IL_000c: call ""int Program.GetOffset(ref T)"" - IL_0011: ldloca.s V_2 - IL_0013: ldc.i4.4 - IL_0014: ldc.i4.1 - IL_0015: ldloc.0 - IL_0016: ldobj ""T"" - IL_001b: box ""T"" - IL_0020: call ""DummyHandler..ctor(int, int, IMoveable)"" - IL_0025: ldloca.s V_2 - IL_0027: ldstr ""log:"" - IL_002c: call ""void DummyHandler.AppendLiteral(string)"" - IL_0031: ldloca.s V_2 - IL_0033: ldc.i4.0 - IL_0034: call ""void DummyHandler.AppendFormatted(int)"" - IL_0039: ldloc.2 - IL_003a: constrained. ""T"" - IL_0040: callvirt ""void IMoveable.GetName(int, DummyHandler)"" - IL_0045: ret + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: box ""T"" + IL_000d: ldarg.0 + IL_000e: call ""int Program.GetOffset(ref T)"" + IL_0013: ldloca.s V_1 + IL_0015: ldc.i4.4 + IL_0016: ldc.i4.1 + IL_0017: ldloc.0 + IL_0018: box ""T"" + IL_001d: call ""DummyHandler..ctor(int, int, IMoveable)"" + IL_0022: ldloca.s V_1 + IL_0024: ldstr ""log:"" + IL_0029: call ""void DummyHandler.AppendLiteral(string)"" + IL_002e: ldloca.s V_1 + IL_0030: ldc.i4.0 + IL_0031: call ""void DummyHandler.AppendFormatted(int)"" + IL_0036: ldloc.1 + IL_0037: callvirt ""void IMoveable.GetName(int, DummyHandler)"" + IL_003c: ret } "); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index 38dcc0729c2d3..e2a85c038cefe 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -9716,61 +9716,60 @@ public CustomHandler(int literalLength, int formattedCount," + refness + @" C c) verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.FailsILVerify : Verification.Skipped); verifier.VerifyIL("", refness == "in" ? @" { - // Code size 46 (0x2e) + // Code size 47 (0x2f) .maxstack 4 .locals init (C V_0, //c - C& V_1, + C V_1, CustomHandler V_2) IL_0000: ldc.i4.1 IL_0001: newobj ""C..ctor(int)"" IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: call ""ref C Program.<
$>g__GetC|0_0(ref C)"" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldind.ref + IL_000e: ldind.ref + IL_000f: stloc.1 + IL_0010: ldloc.1 IL_0011: ldc.i4.7 IL_0012: ldc.i4.0 - IL_0013: ldloc.1 - IL_0014: newobj ""CustomHandler..ctor(int, int, in C)"" - IL_0019: stloc.2 - IL_001a: ldloca.s V_2 - IL_001c: ldstr ""literal"" - IL_0021: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0026: pop - IL_0027: ldloc.2 - IL_0028: callvirt ""void C.M(CustomHandler)"" - IL_002d: ret + IL_0013: ldloca.s V_1 + IL_0015: newobj ""CustomHandler..ctor(int, int, in C)"" + IL_001a: stloc.2 + IL_001b: ldloca.s V_2 + IL_001d: ldstr ""literal"" + IL_0022: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0027: pop + IL_0028: ldloc.2 + IL_0029: callvirt ""void C.M(CustomHandler)"" + IL_002e: ret } " : @" { - // Code size 48 (0x30) + // Code size 47 (0x2f) .maxstack 5 .locals init (C V_0, //c - C& V_1, + C V_1, CustomHandler V_2) IL_0000: ldc.i4.1 IL_0001: newobj ""C..ctor(int)"" IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: call ""ref C Program.<
$>g__GetC|0_0(ref C)"" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldind.ref + IL_000e: ldind.ref + IL_000f: stloc.1 + IL_0010: ldloc.1 IL_0011: ldloca.s V_2 IL_0013: ldc.i4.7 IL_0014: ldc.i4.0 IL_0015: ldloc.1 - IL_0016: ldind.ref - IL_0017: call ""CustomHandler..ctor(int, int, C)"" - IL_001c: ldloca.s V_2 - IL_001e: ldstr ""literal"" - IL_0023: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0028: pop - IL_0029: ldloc.2 - IL_002a: callvirt ""void C.M(CustomHandler)"" - IL_002f: ret + IL_0016: call ""CustomHandler..ctor(int, int, C)"" + IL_001b: ldloca.s V_2 + IL_001d: ldstr ""literal"" + IL_0022: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0027: pop + IL_0028: ldloc.2 + IL_0029: callvirt ""void C.M(CustomHandler)"" + IL_002e: ret } "); @@ -9822,31 +9821,30 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyDiagnostics(); verifier.VerifyIL($"Program.<
$>g__localFunc|0_0({parameterRefness} C)", @" { - // Code size 43 (0x2b) + // Code size 42 (0x2a) .maxstack 5 - .locals init (C& V_0, + .locals init (C V_0, CustomHandler V_1) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: newobj ""C..ctor(int)"" IL_0007: stind.ref IL_0008: ldarg.0 - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldind.ref + IL_0009: ldind.ref + IL_000a: stloc.0 + IL_000b: ldloc.0 IL_000c: ldloca.s V_1 IL_000e: ldc.i4.7 IL_000f: ldc.i4.0 IL_0010: ldloc.0 - IL_0011: ldind.ref - IL_0012: call ""CustomHandler..ctor(int, int, C)"" - IL_0017: ldloca.s V_1 - IL_0019: ldstr ""literal"" - IL_001e: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0023: pop - IL_0024: ldloc.1 - IL_0025: callvirt ""void C.M(CustomHandler)"" - IL_002a: ret + IL_0011: call ""CustomHandler..ctor(int, int, C)"" + IL_0016: ldloca.s V_1 + IL_0018: ldstr ""literal"" + IL_001d: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0022: pop + IL_0023: ldloc.1 + IL_0024: callvirt ""void C.M(CustomHandler)"" + IL_0029: ret } "); @@ -18585,41 +18583,40 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyIL("", """ { - // Code size 53 (0x35) - .maxstack 5 - .locals init (C V_0, //c - C& V_1, //c2 - C V_2, //otherC - C& V_3, - CustomHandler V_4) - IL_0000: ldc.i4.5 - IL_0001: newobj "C..ctor(int)" - IL_0006: stloc.0 - IL_0007: ldloca.s V_0 - IL_0009: stloc.1 - IL_000a: ldnull - IL_000b: stloc.2 - IL_000c: ldloc.1 - IL_000d: stloc.3 - IL_000e: ldloc.3 - IL_000f: ldind.ref - IL_0010: ldloca.s V_4 - IL_0012: ldc.i4.7 - IL_0013: ldc.i4.0 - IL_0014: ldloc.3 - IL_0015: ldind.ref - IL_0016: call "CustomHandler..ctor(int, int, C)" - IL_001b: ldloca.s V_4 - IL_001d: ldstr "literal" - IL_0022: call "bool CustomHandler.AppendLiteral(string)" - IL_0027: pop - IL_0028: ldloc.s V_4 - IL_002a: ldloca.s V_2 - IL_002c: dup - IL_002d: stloc.1 - IL_002e: ldind.ref - IL_002f: callvirt "void C.M(CustomHandler, C)" - IL_0034: ret + // Code size 52 (0x34) + .maxstack 5 + .locals init (C V_0, //c + C& V_1, //c2 + C V_2, //otherC + C V_3, + CustomHandler V_4) + IL_0000: ldc.i4.5 + IL_0001: newobj "C..ctor(int)" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: stloc.1 + IL_000a: ldnull + IL_000b: stloc.2 + IL_000c: ldloc.1 + IL_000d: ldind.ref + IL_000e: stloc.3 + IL_000f: ldloc.3 + IL_0010: ldloca.s V_4 + IL_0012: ldc.i4.7 + IL_0013: ldc.i4.0 + IL_0014: ldloc.3 + IL_0015: call "CustomHandler..ctor(int, int, C)" + IL_001a: ldloca.s V_4 + IL_001c: ldstr "literal" + IL_0021: call "bool CustomHandler.AppendLiteral(string)" + IL_0026: pop + IL_0027: ldloc.s V_4 + IL_0029: ldloca.s V_2 + IL_002b: dup + IL_002c: stloc.1 + IL_002d: ldind.ref + IL_002e: callvirt "void C.M(CustomHandler, C)" + IL_0033: ret } """); } @@ -18669,12 +18666,12 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyIL("", """ { - // Code size 53 (0x35) + // Code size 52 (0x34) .maxstack 6 .locals init (C V_0, //c C& V_1, //c2 C V_2, //otherC - C& V_3, + C V_3, CustomHandler V_4) IL_0000: ldc.i4.5 IL_0001: newobj "C..ctor(int)" @@ -18684,9 +18681,9 @@ .locals init (C V_0, //c IL_000a: ldnull IL_000b: stloc.2 IL_000c: ldloc.1 - IL_000d: stloc.3 - IL_000e: ldloc.3 - IL_000f: ldind.ref + IL_000d: ldind.ref + IL_000e: stloc.3 + IL_000f: ldloc.3 IL_0010: ldloca.s V_2 IL_0012: dup IL_0013: stloc.1 @@ -18695,15 +18692,14 @@ .locals init (C V_0, //c IL_0017: ldc.i4.7 IL_0018: ldc.i4.0 IL_0019: ldloc.3 - IL_001a: ldind.ref - IL_001b: call "CustomHandler..ctor(int, int, C)" - IL_0020: ldloca.s V_4 - IL_0022: ldstr "literal" - IL_0027: call "bool CustomHandler.AppendLiteral(string)" - IL_002c: pop - IL_002d: ldloc.s V_4 - IL_002f: callvirt "void C.M(C, CustomHandler)" - IL_0034: ret + IL_001a: call "CustomHandler..ctor(int, int, C)" + IL_001f: ldloca.s V_4 + IL_0021: ldstr "literal" + IL_0026: call "bool CustomHandler.AppendLiteral(string)" + IL_002b: pop + IL_002c: ldloc.s V_4 + IL_002e: callvirt "void C.M(C, CustomHandler)" + IL_0033: ret } """); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs index 6e6458b095c92..795f62518503d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs @@ -7957,61 +7957,60 @@ public CustomHandler(int literalLength, int formattedCount," + refness + @" C c) verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.FailsILVerify : Verification.Skipped); verifier.VerifyIL("", refness == "in" ? @" { - // Code size 46 (0x2e) + // Code size 47 (0x2f) .maxstack 4 .locals init (C V_0, //c - C& V_1, + C V_1, CustomHandler V_2) IL_0000: ldc.i4.1 IL_0001: newobj ""C..ctor(int)"" IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: call ""ref C Program.<
$>g__GetC|0_0(ref C)"" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldind.ref + IL_000e: ldind.ref + IL_000f: stloc.1 + IL_0010: ldloc.1 IL_0011: ldc.i4.7 IL_0012: ldc.i4.0 - IL_0013: ldloc.1 - IL_0014: newobj ""CustomHandler..ctor(int, int, in C)"" - IL_0019: stloc.2 - IL_001a: ldloca.s V_2 - IL_001c: ldstr ""literal"" - IL_0021: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0026: pop - IL_0027: ldloc.2 - IL_0028: callvirt ""void C.M(CustomHandler)"" - IL_002d: ret + IL_0013: ldloca.s V_1 + IL_0015: newobj ""CustomHandler..ctor(int, int, in C)"" + IL_001a: stloc.2 + IL_001b: ldloca.s V_2 + IL_001d: ldstr ""literal"" + IL_0022: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0027: pop + IL_0028: ldloc.2 + IL_0029: callvirt ""void C.M(CustomHandler)"" + IL_002e: ret } " : @" { - // Code size 48 (0x30) + // Code size 47 (0x2f) .maxstack 5 .locals init (C V_0, //c - C& V_1, + C V_1, CustomHandler V_2) IL_0000: ldc.i4.1 IL_0001: newobj ""C..ctor(int)"" IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: call ""ref C Program.<
$>g__GetC|0_0(ref C)"" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldind.ref + IL_000e: ldind.ref + IL_000f: stloc.1 + IL_0010: ldloc.1 IL_0011: ldloca.s V_2 IL_0013: ldc.i4.7 IL_0014: ldc.i4.0 IL_0015: ldloc.1 - IL_0016: ldind.ref - IL_0017: call ""CustomHandler..ctor(int, int, C)"" - IL_001c: ldloca.s V_2 - IL_001e: ldstr ""literal"" - IL_0023: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0028: pop - IL_0029: ldloc.2 - IL_002a: callvirt ""void C.M(CustomHandler)"" - IL_002f: ret + IL_0016: call ""CustomHandler..ctor(int, int, C)"" + IL_001b: ldloca.s V_2 + IL_001d: ldstr ""literal"" + IL_0022: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0027: pop + IL_0028: ldloc.2 + IL_0029: callvirt ""void C.M(CustomHandler)"" + IL_002e: ret } "); @@ -8066,31 +8065,30 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyDiagnostics(); verifier.VerifyIL($"Program.<
$>g__localFunc|0_0({parameterRefness} C)", @" { - // Code size 43 (0x2b) + // Code size 42 (0x2a) .maxstack 5 - .locals init (C& V_0, + .locals init (C V_0, CustomHandler V_1) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: newobj ""C..ctor(int)"" IL_0007: stind.ref IL_0008: ldarg.0 - IL_0009: stloc.0 - IL_000a: ldloc.0 - IL_000b: ldind.ref + IL_0009: ldind.ref + IL_000a: stloc.0 + IL_000b: ldloc.0 IL_000c: ldloca.s V_1 IL_000e: ldc.i4.7 IL_000f: ldc.i4.0 IL_0010: ldloc.0 - IL_0011: ldind.ref - IL_0012: call ""CustomHandler..ctor(int, int, C)"" - IL_0017: ldloca.s V_1 - IL_0019: ldstr ""literal"" - IL_001e: call ""bool CustomHandler.AppendLiteral(string)"" - IL_0023: pop - IL_0024: ldloc.1 - IL_0025: callvirt ""void C.M(CustomHandler)"" - IL_002a: ret + IL_0011: call ""CustomHandler..ctor(int, int, C)"" + IL_0016: ldloca.s V_1 + IL_0018: ldstr ""literal"" + IL_001d: call ""bool CustomHandler.AppendLiteral(string)"" + IL_0022: pop + IL_0023: ldloc.1 + IL_0024: callvirt ""void C.M(CustomHandler)"" + IL_0029: ret } "); From 7f60e362ae4d5be675f0a42570a4fe23965e67f5 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 23 May 2024 10:46:31 -0700 Subject: [PATCH 3/7] Add new test baselines --- .../LocalRewriter/LocalRewriter_Call.cs | 10 +- .../Semantic/Semantics/InterpolationTests.cs | 309 +++++++++++++++--- 2 files changed, 268 insertions(+), 51 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 242a98b3ba65c..2081d8afb3faa 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -677,11 +677,11 @@ private ImmutableArray VisitArgumentsAndCaptureReceiverIfNeeded } else { - if (rewrittenReceiver.Type.IsReferenceType) - { - refKind = RefKind.None; - } - else + //if (rewrittenReceiver.Type.IsReferenceType) + //{ + // refKind = RefKind.None; + //} + //else { refKind = rewrittenReceiver.GetRefKind(); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index e2a85c038cefe..cb33e00a057f7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -18548,8 +18548,7 @@ public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTy using System.Runtime.CompilerServices; C c = new C(5); ref C c2 = ref c; -C otherC = null; -c2.M({{expression}}, c2 = ref otherC); +c2.M({{expression}}, c2 = null); public class C { @@ -18557,7 +18556,7 @@ public class C public C(int i) => Prop = i; public void M([InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c, C cNull) { - Console.WriteLine(cNull is null); + Console.WriteLine(cNull is null ? "cNull" : null); Console.WriteLine(c.ToString()); } } @@ -18575,7 +18574,7 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }); var verifier = CompileAndVerify(comp, expectedOutput: """ -True +cNull c.Prop:5 literal:literal """); @@ -18583,40 +18582,41 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyIL("", """ { - // Code size 52 (0x34) + // Code size 53 (0x35) .maxstack 5 .locals init (C V_0, //c C& V_1, //c2 - C V_2, //otherC - C V_3, - CustomHandler V_4) + C& V_2, + CustomHandler V_3, + C V_4) IL_0000: ldc.i4.5 IL_0001: newobj "C..ctor(int)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: stloc.1 - IL_000a: ldnull + IL_000a: ldloc.1 IL_000b: stloc.2 - IL_000c: ldloc.1 + IL_000c: ldloc.2 IL_000d: ldind.ref - IL_000e: stloc.3 - IL_000f: ldloc.3 - IL_0010: ldloca.s V_4 - IL_0012: ldc.i4.7 - IL_0013: ldc.i4.0 - IL_0014: ldloc.3 - IL_0015: call "CustomHandler..ctor(int, int, C)" - IL_001a: ldloca.s V_4 - IL_001c: ldstr "literal" - IL_0021: call "bool CustomHandler.AppendLiteral(string)" - IL_0026: pop - IL_0027: ldloc.s V_4 - IL_0029: ldloca.s V_2 - IL_002b: dup - IL_002c: stloc.1 - IL_002d: ldind.ref - IL_002e: callvirt "void C.M(CustomHandler, C)" - IL_0033: ret + IL_000e: ldloca.s V_3 + IL_0010: ldc.i4.7 + IL_0011: ldc.i4.0 + IL_0012: ldloc.2 + IL_0013: ldind.ref + IL_0014: call "CustomHandler..ctor(int, int, C)" + IL_0019: ldloca.s V_3 + IL_001b: ldstr "literal" + IL_0020: call "bool CustomHandler.AppendLiteral(string)" + IL_0025: pop + IL_0026: ldloc.3 + IL_0027: ldloc.1 + IL_0028: ldnull + IL_0029: dup + IL_002a: stloc.s V_4 + IL_002c: stind.ref + IL_002d: ldloc.s V_4 + IL_002f: callvirt "void C.M(CustomHandler, C)" + IL_0034: ret } """); } @@ -18631,8 +18631,7 @@ public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTy using System.Runtime.CompilerServices; C c = new C(5); ref C c2 = ref c; -C otherC = null; -c2.M(c2 = ref otherC, {{expression}}); +c2.M(c2 = null, {{expression}}); public class C { @@ -18640,7 +18639,7 @@ public class C public C(int i) => Prop = i; public void M(C cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c) { - Console.WriteLine(cNull is null); + Console.WriteLine(cNull is null ? "cNull" : null); Console.WriteLine(c.ToString()); } } @@ -18657,9 +18656,10 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }); + // execution crashes as `c` is null var verifier = CompileAndVerify(comp, expectedOutput: """ -True -c.Prop:5 +cNull +c.Property:5 literal:literal """); verifier.VerifyDiagnostics(); @@ -18670,7 +18670,7 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL .maxstack 6 .locals init (C V_0, //c C& V_1, //c2 - C V_2, //otherC + C& V_2, C V_3, CustomHandler V_4) IL_0000: ldc.i4.5 @@ -18678,20 +18678,21 @@ .locals init (C V_0, //c IL_0006: stloc.0 IL_0007: ldloca.s V_0 IL_0009: stloc.1 - IL_000a: ldnull + IL_000a: ldloc.1 IL_000b: stloc.2 - IL_000c: ldloc.1 + IL_000c: ldloc.2 IL_000d: ldind.ref - IL_000e: stloc.3 - IL_000f: ldloc.3 - IL_0010: ldloca.s V_2 - IL_0012: dup - IL_0013: stloc.1 - IL_0014: ldind.ref - IL_0015: ldloca.s V_4 - IL_0017: ldc.i4.7 - IL_0018: ldc.i4.0 - IL_0019: ldloc.3 + IL_000e: ldloc.1 + IL_000f: ldnull + IL_0010: dup + IL_0011: stloc.3 + IL_0012: stind.ref + IL_0013: ldloc.3 + IL_0014: ldloca.s V_4 + IL_0016: ldc.i4.7 + IL_0017: ldc.i4.0 + IL_0018: ldloc.2 + IL_0019: ldind.ref IL_001a: call "CustomHandler..ctor(int, int, C)" IL_001f: ldloca.s V_4 IL_0021: ldstr "literal" @@ -18701,6 +18702,222 @@ .locals init (C V_0, //c IL_002e: callvirt "void C.M(C, CustomHandler)" IL_0033: ret } +"""); + } + + [Theory] + [CombinatorialData] + public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceConstrainedRefReceiver( + [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) + { + var code = $$""" +using System; +using System.Runtime.CompilerServices; + +class Program +{ + static void Main() + { + C c = new C(5); + Test(ref c); + } + + static void Test(ref T c2) where T : I1 + { + c2.M(c2 = default, {{expression}}); + } +} + +public interface I1 +{ + int Prop { get; } + void M(I1 cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c); +} + +public class C : I1 +{ + public int Prop { get; } + public C(int i) => Prop = i; + public void M(I1 cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c) + { + Console.WriteLine(cNull is null); + Console.WriteLine(c.ToString()); + } +} + +public partial struct CustomHandler +{ + public CustomHandler(int literalLength, int formattedCount, I1 c) : this(literalLength, formattedCount) + { + _builder.AppendLine("c.Prop:" + c.Prop.ToString()); + } +} +"""; + + var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); + + var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }, options: TestOptions.DebugExe); + var verifier = CompileAndVerify(comp, expectedOutput: """ +True +c.Prop:5 +literal:literal +"""); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.Test(ref T)", """ +{ + // Code size 104 (0x68) + .maxstack 6 + .locals init (T& V_0, + T V_1, + T& V_2, + T V_3, + CustomHandler V_4) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.2 + IL_0003: ldloca.s V_3 + IL_0005: initobj "T" + IL_000b: ldloc.3 + IL_000c: box "T" + IL_0011: brtrue.s IL_001e + IL_0013: ldloc.2 + IL_0014: ldobj "T" + IL_0019: stloc.1 + IL_001a: ldloca.s V_1 + IL_001c: br.s IL_001f + IL_001e: ldloc.2 + IL_001f: stloc.0 + IL_0020: ldloc.0 + IL_0021: ldarg.0 + IL_0022: ldloca.s V_3 + IL_0024: initobj "T" + IL_002a: ldloc.3 + IL_002b: dup + IL_002c: stloc.3 + IL_002d: stobj "T" + IL_0032: ldloc.3 + IL_0033: box "T" + IL_0038: ldloca.s V_4 + IL_003a: ldc.i4.7 + IL_003b: ldc.i4.0 + IL_003c: ldloc.0 + IL_003d: ldobj "T" + IL_0042: box "T" + IL_0047: call "CustomHandler..ctor(int, int, I1)" + IL_004c: ldloca.s V_4 + IL_004e: ldstr "literal" + IL_0053: call "bool CustomHandler.AppendLiteral(string)" + IL_0058: pop + IL_0059: ldloc.s V_4 + IL_005b: constrained. "T" + IL_0061: callvirt "void I1.M(I1, CustomHandler)" + IL_0066: nop + IL_0067: ret +} +"""); + } + + [Theory] + [CombinatorialData] + public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceAndClassConstrainedRefReceiver( + [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) + { + var code = $$""" +using System; +using System.Runtime.CompilerServices; + +class Program +{ + static void Main() + { + C c = new C(5); + Test(ref c); + } + + static void Test(ref T c2) where T : class, I1 + { + c2.M(c2 = default, {{expression}}); + } +} + +public interface I1 +{ + int Prop { get; } + void M(I1 cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c); +} + +public class C : I1 +{ + public int Prop { get; } + public C(int i) => Prop = i; + public void M(I1 cNull, [InterpolatedStringHandlerArgumentAttribute("")] CustomHandler c) + { + Console.WriteLine(cNull is null); + Console.WriteLine(c.ToString()); + } +} + +public partial struct CustomHandler +{ + public CustomHandler(int literalLength, int formattedCount, I1 c) : this(literalLength, formattedCount) + { + _builder.AppendLine("c.Prop:" + c.Prop.ToString()); + } +} +"""; + + var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); + + var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }, options: TestOptions.DebugExe); + var verifier = CompileAndVerify(comp, expectedOutput: """ +True +c.Prop:5 +literal:literal +"""); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.Test(ref T)", """ +{ + // Code size 82 (0x52) + .maxstack 6 + .locals init (T& V_0, + T V_1, + T V_2, + CustomHandler V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldobj "T" + IL_0007: stloc.1 + IL_0008: ldloca.s V_1 + IL_000a: stloc.0 + IL_000b: ldloc.0 + IL_000c: ldarg.0 + IL_000d: ldloca.s V_2 + IL_000f: initobj "T" + IL_0015: ldloc.2 + IL_0016: dup + IL_0017: stloc.2 + IL_0018: stobj "T" + IL_001d: ldloc.2 + IL_001e: box "T" + IL_0023: ldloca.s V_3 + IL_0025: ldc.i4.7 + IL_0026: ldc.i4.0 + IL_0027: ldloc.0 + IL_0028: ldobj "T" + IL_002d: box "T" + IL_0032: call "CustomHandler..ctor(int, int, I1)" + IL_0037: ldloca.s V_3 + IL_0039: ldstr "literal" + IL_003e: call "bool CustomHandler.AppendLiteral(string)" + IL_0043: pop + IL_0044: ldloc.3 + IL_0045: constrained. "T" + IL_004b: callvirt "void I1.M(I1, CustomHandler)" + IL_0050: nop + IL_0051: ret +} """); } } From 6656166112302a4daa0145aa84f8ada04988a01b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 23 May 2024 11:08:30 -0700 Subject: [PATCH 4/7] Update tests with fix --- .../LocalRewriter/LocalRewriter_Call.cs | 10 +- .../Semantic/Semantics/InterpolationTests.cs | 131 +++++++++--------- 2 files changed, 67 insertions(+), 74 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 2081d8afb3faa..242a98b3ba65c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -677,11 +677,11 @@ private ImmutableArray VisitArgumentsAndCaptureReceiverIfNeeded } else { - //if (rewrittenReceiver.Type.IsReferenceType) - //{ - // refKind = RefKind.None; - //} - //else + if (rewrittenReceiver.Type.IsReferenceType) + { + refKind = RefKind.None; + } + else { refKind = rewrittenReceiver.GetRefKind(); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index cb33e00a057f7..2dcaf495f551d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -18582,11 +18582,11 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL verifier.VerifyIL("", """ { - // Code size 53 (0x35) + // Code size 52 (0x34) .maxstack 5 .locals init (C V_0, //c C& V_1, //c2 - C& V_2, + C V_2, CustomHandler V_3, C V_4) IL_0000: ldc.i4.5 @@ -18595,28 +18595,27 @@ .locals init (C V_0, //c IL_0007: ldloca.s V_0 IL_0009: stloc.1 IL_000a: ldloc.1 - IL_000b: stloc.2 - IL_000c: ldloc.2 - IL_000d: ldind.ref + IL_000b: ldind.ref + IL_000c: stloc.2 + IL_000d: ldloc.2 IL_000e: ldloca.s V_3 IL_0010: ldc.i4.7 IL_0011: ldc.i4.0 IL_0012: ldloc.2 - IL_0013: ldind.ref - IL_0014: call "CustomHandler..ctor(int, int, C)" - IL_0019: ldloca.s V_3 - IL_001b: ldstr "literal" - IL_0020: call "bool CustomHandler.AppendLiteral(string)" - IL_0025: pop - IL_0026: ldloc.3 - IL_0027: ldloc.1 - IL_0028: ldnull - IL_0029: dup - IL_002a: stloc.s V_4 - IL_002c: stind.ref - IL_002d: ldloc.s V_4 - IL_002f: callvirt "void C.M(CustomHandler, C)" - IL_0034: ret + IL_0013: call "CustomHandler..ctor(int, int, C)" + IL_0018: ldloca.s V_3 + IL_001a: ldstr "literal" + IL_001f: call "bool CustomHandler.AppendLiteral(string)" + IL_0024: pop + IL_0025: ldloc.3 + IL_0026: ldloc.1 + IL_0027: ldnull + IL_0028: dup + IL_0029: stloc.s V_4 + IL_002b: stind.ref + IL_002c: ldloc.s V_4 + IL_002e: callvirt "void C.M(CustomHandler, C)" + IL_0033: ret } """); } @@ -18656,21 +18655,20 @@ public CustomHandler(int literalLength, int formattedCount, C c) : this(literalL var handler = GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: true); var comp = CreateCompilation(new[] { code, InterpolatedStringHandlerArgumentAttribute, handler }); - // execution crashes as `c` is null var verifier = CompileAndVerify(comp, expectedOutput: """ cNull -c.Property:5 +c.Prop:5 literal:literal """); verifier.VerifyDiagnostics(); verifier.VerifyIL("", """ { - // Code size 52 (0x34) + // Code size 51 (0x33) .maxstack 6 .locals init (C V_0, //c C& V_1, //c2 - C& V_2, + C V_2, C V_3, CustomHandler V_4) IL_0000: ldc.i4.5 @@ -18679,9 +18677,9 @@ .locals init (C V_0, //c IL_0007: ldloca.s V_0 IL_0009: stloc.1 IL_000a: ldloc.1 - IL_000b: stloc.2 - IL_000c: ldloc.2 - IL_000d: ldind.ref + IL_000b: ldind.ref + IL_000c: stloc.2 + IL_000d: ldloc.2 IL_000e: ldloc.1 IL_000f: ldnull IL_0010: dup @@ -18692,15 +18690,14 @@ .locals init (C V_0, //c IL_0016: ldc.i4.7 IL_0017: ldc.i4.0 IL_0018: ldloc.2 - IL_0019: ldind.ref - IL_001a: call "CustomHandler..ctor(int, int, C)" - IL_001f: ldloca.s V_4 - IL_0021: ldstr "literal" - IL_0026: call "bool CustomHandler.AppendLiteral(string)" - IL_002b: pop - IL_002c: ldloc.s V_4 - IL_002e: callvirt "void C.M(C, CustomHandler)" - IL_0033: ret + IL_0019: call "CustomHandler..ctor(int, int, C)" + IL_001e: ldloca.s V_4 + IL_0020: ldstr "literal" + IL_0025: call "bool CustomHandler.AppendLiteral(string)" + IL_002a: pop + IL_002b: ldloc.s V_4 + IL_002d: callvirt "void C.M(C, CustomHandler)" + IL_0032: ret } """); } @@ -18879,44 +18876,40 @@ public CustomHandler(int literalLength, int formattedCount, I1 c) : this(literal verifier.VerifyIL("Program.Test(ref T)", """ { - // Code size 82 (0x52) + // Code size 73 (0x49) .maxstack 6 - .locals init (T& V_0, + .locals init (T V_0, T V_1, - T V_2, - CustomHandler V_3) + CustomHandler V_2) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldobj "T" - IL_0007: stloc.1 - IL_0008: ldloca.s V_1 - IL_000a: stloc.0 - IL_000b: ldloc.0 - IL_000c: ldarg.0 - IL_000d: ldloca.s V_2 - IL_000f: initobj "T" - IL_0015: ldloc.2 - IL_0016: dup - IL_0017: stloc.2 - IL_0018: stobj "T" - IL_001d: ldloc.2 - IL_001e: box "T" - IL_0023: ldloca.s V_3 - IL_0025: ldc.i4.7 - IL_0026: ldc.i4.0 - IL_0027: ldloc.0 - IL_0028: ldobj "T" - IL_002d: box "T" - IL_0032: call "CustomHandler..ctor(int, int, I1)" - IL_0037: ldloca.s V_3 - IL_0039: ldstr "literal" - IL_003e: call "bool CustomHandler.AppendLiteral(string)" - IL_0043: pop - IL_0044: ldloc.3 - IL_0045: constrained. "T" - IL_004b: callvirt "void I1.M(I1, CustomHandler)" - IL_0050: nop - IL_0051: ret + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: box "T" + IL_000e: ldarg.0 + IL_000f: ldloca.s V_1 + IL_0011: initobj "T" + IL_0017: ldloc.1 + IL_0018: dup + IL_0019: stloc.1 + IL_001a: stobj "T" + IL_001f: ldloc.1 + IL_0020: box "T" + IL_0025: ldloca.s V_2 + IL_0027: ldc.i4.7 + IL_0028: ldc.i4.0 + IL_0029: ldloc.0 + IL_002a: box "T" + IL_002f: call "CustomHandler..ctor(int, int, I1)" + IL_0034: ldloca.s V_2 + IL_0036: ldstr "literal" + IL_003b: call "bool CustomHandler.AppendLiteral(string)" + IL_0040: pop + IL_0041: ldloc.2 + IL_0042: callvirt "void I1.M(I1, CustomHandler)" + IL_0047: nop + IL_0048: ret } """); } From 3262eda633a685662ad077a3b9168bf7ed85eaa7 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 30 May 2024 13:51:31 -0700 Subject: [PATCH 5/7] Add WorkItem link --- .../CSharp/Test/Semantic/Semantics/InterpolationTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index 2dcaf495f551d..bc7aef46fae75 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -18538,7 +18538,7 @@ public static void M(ref A a) {} Diagnostic(ErrorCode.ERR_BadArgRef, @"$""{1}""").WithArguments("1", "ref").WithLocation(8, 29)); } - [Theory] + [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18620,7 +18620,7 @@ .locals init (C V_0, //c """); } - [Theory] + [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver_ReverseOrder( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18702,7 +18702,7 @@ .locals init (C V_0, //c """); } - [Theory] + [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceConstrainedRefReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18815,7 +18815,7 @@ .locals init (T& V_0, """); } - [Theory] + [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceAndClassConstrainedRefReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) From 48af3ac973399bf26ecc61c9de42d5051d93aa6b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 30 May 2024 13:57:27 -0700 Subject: [PATCH 6/7] Remove redundant check --- .../CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 242a98b3ba65c..8c1b126d3081f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -686,7 +686,6 @@ private ImmutableArray VisitArgumentsAndCaptureReceiverIfNeeded refKind = rewrittenReceiver.GetRefKind(); if (refKind == RefKind.None && - !rewrittenReceiver.Type.IsReferenceType && Binder.HasHome(rewrittenReceiver, Binder.AddressKind.Constrained, _factory.CurrentFunction, From 02d592d6611ab934cc95e8e181ffe0a491d2066c Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 30 May 2024 14:09:17 -0700 Subject: [PATCH 7/7] Fix linked issue --- .../CSharp/Test/Semantic/Semantics/InterpolationTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index bc7aef46fae75..d7af039b84eeb 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -18538,7 +18538,7 @@ public static void M(ref A a) {} Diagnostic(ErrorCode.ERR_BadArgRef, @"$""{1}""").WithArguments("1", "ref").WithLocation(8, 29)); } - [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/73667")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18620,7 +18620,7 @@ .locals init (C V_0, //c """); } - [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/73667")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_ReferenceTypeReferenceReceiver_ReverseOrder( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18702,7 +18702,7 @@ .locals init (C V_0, //c """); } - [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/73667")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceConstrainedRefReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression) @@ -18815,7 +18815,7 @@ .locals init (T& V_0, """); } - [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/73631")] + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/73667")] [CombinatorialData] public void InterpolatedStringHandlerArgumentAttribute_ThisParameter_InterfaceAndClassConstrainedRefReceiver( [CombinatorialValues(@"$""literal""", @"$""literal"" + $""""")] string expression)