From 6bc0d9b3a892d7d459c4b577b61c863c3bfdff44 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 10 Jan 2024 13:36:26 -0800 Subject: [PATCH] Enable some dynamic collection expression tests which were disabled during merge from 'main'. (#71558) --- .../Semantics/CollectionExpressionTests.cs | 545 ++++++++++++++++-- 1 file changed, 487 insertions(+), 58 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs index 98f8be4a5752a..e3806364c84e4 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs @@ -7382,12 +7382,12 @@ static void Main() Diagnostic(ErrorCode.ERR_NoImplicitConv, "s").WithArguments("object", "int").WithLocation(8, 41)); } - [Theory(Skip = "// PROTOTYPE(ParamsCollections): Adjust for new dynamic behavior")] + [Theory] [InlineData("object[]")] - [InlineData("List")] + [InlineData("MyList")] [InlineData("int[]")] - [InlineData("List")] - public void SpreadElement_Dynamic_01(string resultType) + [InlineData("MyList")] + public void SpreadElement_Dynamic_01_DynamicBinding(string resultType) { string source = $$""" using System.Collections.Generic; @@ -7403,6 +7403,15 @@ static void Main() a.Report(); } } + + namespace System.Collections.Generic + { + class MyList : List + { + public new void Add(T x) => base.Add(x); + public void Add(string x) => throw null; + } + } """; var verifier = CompileAndVerify(new[] { source, s_collectionExtensions }, references: new[] { CSharpRef }, options: TestOptions.ReleaseExe, expectedOutput: "[1, 2, 3], "); if (resultType == "int[]") @@ -7470,17 +7479,85 @@ .locals init (int V_0, } """); } - else if (resultType == "List") + else if (resultType == "MyList") { verifier.VerifyIL("Program.F", """ { // Code size 141 (0x8d) .maxstack 9 - .locals init (System.Collections.Generic.List V_0, + .locals init (System.Collections.Generic.MyList V_0, System.Collections.Generic.List.Enumerator V_1, object V_2) - IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" + IL_0005: stloc.0 + IL_0006: ldarg.0 + IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_000c: stloc.1 + .try + { + IL_000d: br.s IL_0072 + IL_000f: ldloca.s V_1 + IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0016: stloc.2 + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_001c: brtrue.s IL_005c + IL_001e: ldc.i4 0x100 + IL_0023: ldstr "Add" + IL_0028: ldnull + IL_0029: ldtoken "Program" + IL_002e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0033: ldc.i4.2 + IL_0034: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0039: dup + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.1 + IL_003c: ldnull + IL_003d: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.1 + IL_0045: ldc.i4.0 + IL_0046: ldnull + IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_004c: stelem.ref + IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_006b: ldloc.0 + IL_006c: ldloc.2 + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" + IL_0072: ldloca.s V_1 + IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0079: brtrue.s IL_000f + IL_007b: leave.s IL_008b + } + finally + { + IL_007d: ldloca.s V_1 + IL_007f: constrained. "System.Collections.Generic.List.Enumerator" + IL_0085: callvirt "void System.IDisposable.Dispose()" + IL_008a: endfinally + } + IL_008b: ldloc.0 + IL_008c: ret + } + """); + } + else if (resultType == "MyList") + { + verifier.VerifyIL("Program.F", + """ + { + // Code size 141 (0x8d) + .maxstack 9 + .locals init (System.Collections.Generic.MyList V_0, + System.Collections.Generic.List.Enumerator V_1, + object V_2) + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" IL_0005: stloc.0 IL_0006: ldarg.0 IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" @@ -7491,7 +7568,7 @@ .locals init (System.Collections.Generic.List V_0, IL_000f: ldloca.s V_1 IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" IL_0016: stloc.2 - IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_001c: brtrue.s IL_005c IL_001e: ldc.i4 0x100 IL_0023: ldstr "Add" @@ -7513,14 +7590,14 @@ .locals init (System.Collections.Generic.List V_0, IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" IL_004c: stelem.ref IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" - IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" - IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_006b: ldloc.0 IL_006c: ldloc.2 - IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" IL_0072: ldloca.s V_1 IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" IL_0079: brtrue.s IL_000f @@ -7538,6 +7615,111 @@ .locals init (System.Collections.Generic.List V_0, } """); } + else + { + Assert.Equal("object[]", resultType); + } + } + + [Theory] + [InlineData("List")] + [InlineData("List")] + public void SpreadElement_Dynamic_01_StaticBinding(string resultType) + { + string source = $$""" + using System.Collections.Generic; + class Program + { + static {{resultType}} F(List e) + { + return [..e]; + } + static void Main() + { + var a = F([1, 2, 3]); + a.Report(); + } + } + """; + var verifier = CompileAndVerify(new[] { source, s_collectionExtensions }, references: new[] { CSharpRef }, options: TestOptions.ReleaseExe, expectedOutput: "[1, 2, 3], "); + if (resultType == "List") + { + verifier.VerifyIL("Program.F", + """ + { + // Code size 21 (0x15) + .maxstack 3 + .locals init (System.Collections.Generic.List V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: callvirt "int System.Collections.Generic.List.Count.get" + IL_0008: newobj "System.Collections.Generic.List..ctor(int)" + IL_000d: dup + IL_000e: ldloc.0 + IL_000f: callvirt "void System.Collections.Generic.List.AddRange(System.Collections.Generic.IEnumerable)" + IL_0014: ret + } + """); + } + else + { + Assert.Equal("List", resultType); + verifier.VerifyIL("Program.F", + """ + { + // Code size 126 (0x7e) + .maxstack 4 + .locals init (System.Collections.Generic.List V_0, + System.Collections.Generic.List.Enumerator V_1, + object V_2) + IL_0000: ldarg.0 + IL_0001: dup + IL_0002: callvirt "int System.Collections.Generic.List.Count.get" + IL_0007: newobj "System.Collections.Generic.List..ctor(int)" + IL_000c: stloc.0 + IL_000d: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_0012: stloc.1 + .try + { + IL_0013: br.s IL_0063 + IL_0015: ldloca.s V_1 + IL_0017: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_001c: stloc.2 + IL_001d: ldloc.0 + IL_001e: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" + IL_0023: brtrue.s IL_0049 + IL_0025: ldc.i4.0 + IL_0026: ldtoken "int" + IL_002b: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0030: ldtoken "Program" + IL_0035: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_003a: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" + IL_003f: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0044: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" + IL_0049: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" + IL_004e: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" + IL_0053: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" + IL_0058: ldloc.2 + IL_0059: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" + IL_005e: callvirt "void System.Collections.Generic.List.Add(int)" + IL_0063: ldloca.s V_1 + IL_0065: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_006a: brtrue.s IL_0015 + IL_006c: leave.s IL_007c + } + finally + { + IL_006e: ldloca.s V_1 + IL_0070: constrained. "System.Collections.Generic.List.Enumerator" + IL_0076: callvirt "void System.IDisposable.Dispose()" + IL_007b: endfinally + } + IL_007c: ldloc.0 + IL_007d: ret + } + """); + } } [Fact] @@ -17805,21 +17987,30 @@ .locals init (int V_0, """); } - [Fact(Skip = "// PROTOTYPE(ParamsCollections): Adjust for new dynamic behavior")] - public void ListConstruction_Dynamic_01() + [Fact] + public void ListConstruction_Dynamic_01_DynamicBinding() { string source = $$""" using System.Collections.Generic; class Program { - static List F1(List e) => [..e]; - static List F2(List e) => [..e]; + static MyList F1(List e) => [..e]; + static MyList F2(List e) => [..e]; static void Main() { F1([1, 2, 3]).Report(); F2([4, 5]).Report(); } } + + namespace System.Collections.Generic + { + class MyList : List + { + public new void Add(T x) => base.Add(x); + public void Add(string x) => throw null; + } + } """; var verifier = CompileAndVerify( new[] { source, s_collectionExtensions }, @@ -17832,10 +18023,10 @@ static void Main() { // Code size 141 (0x8d) .maxstack 9 - .locals init (System.Collections.Generic.List V_0, + .locals init (System.Collections.Generic.MyList V_0, System.Collections.Generic.List.Enumerator V_1, object V_2) - IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" IL_0005: stloc.0 IL_0006: ldarg.0 IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" @@ -17846,7 +18037,7 @@ .locals init (System.Collections.Generic.List V_0, IL_000f: ldloca.s V_1 IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" IL_0016: stloc.2 - IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_001c: brtrue.s IL_005c IL_001e: ldc.i4 0x100 IL_0023: ldstr "Add" @@ -17868,14 +18059,14 @@ .locals init (System.Collections.Generic.List V_0, IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" IL_004c: stelem.ref IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" - IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" - IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_006b: ldloc.0 IL_006c: ldloc.2 - IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" IL_0072: ldloca.s V_1 IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" IL_0079: brtrue.s IL_000f @@ -17897,10 +18088,10 @@ .locals init (System.Collections.Generic.List V_0, { // Code size 141 (0x8d) .maxstack 9 - .locals init (System.Collections.Generic.List V_0, + .locals init (System.Collections.Generic.MyList V_0, System.Collections.Generic.List.Enumerator V_1, object V_2) - IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" IL_0005: stloc.0 IL_0006: ldarg.0 IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" @@ -17911,7 +18102,7 @@ .locals init (System.Collections.Generic.List V_0, IL_000f: ldloca.s V_1 IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" IL_0016: stloc.2 - IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" IL_001c: brtrue.s IL_005c IL_001e: ldc.i4 0x100 IL_0023: ldstr "Add" @@ -17933,14 +18124,14 @@ .locals init (System.Collections.Generic.List V_0, IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" IL_004c: stelem.ref IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" - IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" - IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" - IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" - IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" IL_006b: ldloc.0 IL_006c: ldloc.2 - IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" IL_0072: ldloca.s V_1 IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" IL_0079: brtrue.s IL_000f @@ -17959,6 +18150,141 @@ .locals init (System.Collections.Generic.List V_0, """); } + [Fact] + public void ListConstruction_Dynamic_01_StaticBinding() + { + string source = $$""" + using System.Collections.Generic; + class Program + { + static List F1(List e) => [..e]; + static List F2(List e) => [..e]; + static void Main() + { + F1([1, 2, 3]).Report(); + F2([4, 5]).Report(); + } + } + """; + var verifier = CompileAndVerify( + new[] { source, s_collectionExtensions }, + targetFramework: TargetFramework.Net80, + options: TestOptions.ReleaseExe, + verify: Verification.FailsPEVerify, + expectedOutput: IncludeExpectedOutput("[1, 2, 3], [4, 5], ")); + verifier.VerifyIL("Program.F1", + """ + { + // Code size 68 (0x44) + .maxstack 5 + .locals init (System.Collections.Generic.List V_0, + System.Span V_1, + int V_2, + System.Span V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: newobj "System.Collections.Generic.List..ctor()" + IL_0007: dup + IL_0008: ldloc.0 + IL_0009: callvirt "int System.Collections.Generic.List.Count.get" + IL_000e: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_0013: dup + IL_0014: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0019: stloc.1 + IL_001a: ldc.i4.0 + IL_001b: stloc.2 + IL_001c: ldloc.0 + IL_001d: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0022: stloc.3 + IL_0023: ldloca.s V_3 + IL_0025: ldloca.s V_1 + IL_0027: ldloc.2 + IL_0028: ldloca.s V_3 + IL_002a: call "int System.Span.Length.get" + IL_002f: call "System.Span System.Span.Slice(int, int)" + IL_0034: call "void System.Span.CopyTo(System.Span)" + IL_0039: ldloc.2 + IL_003a: ldloca.s V_3 + IL_003c: call "int System.Span.Length.get" + IL_0041: add + IL_0042: stloc.2 + IL_0043: ret + } + """); + verifier.VerifyIL("Program.F2", + """ + { + // Code size 153 (0x99) + .maxstack 4 + .locals init (System.Collections.Generic.List V_0, + System.Collections.Generic.List V_1, + System.Span V_2, + int V_3, + System.Collections.Generic.List.Enumerator V_4, + object V_5) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: newobj "System.Collections.Generic.List..ctor()" + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: ldloc.0 + IL_000a: callvirt "int System.Collections.Generic.List.Count.get" + IL_000f: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_0014: ldloc.1 + IL_0015: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_001a: stloc.2 + IL_001b: ldc.i4.0 + IL_001c: stloc.3 + IL_001d: ldloc.0 + IL_001e: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_0023: stloc.s V_4 + .try + { + IL_0025: br.s IL_007e + IL_0027: ldloca.s V_4 + IL_0029: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_002e: stloc.s V_5 + IL_0030: ldloca.s V_2 + IL_0032: ldloc.3 + IL_0033: call "ref int System.Span.this[int].get" + IL_0038: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_003d: brtrue.s IL_0063 + IL_003f: ldc.i4.0 + IL_0040: ldtoken "int" + IL_0045: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_004a: ldtoken "Program" + IL_004f: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0054: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" + IL_0059: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_005e: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0063: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0068: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" + IL_006d: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0072: ldloc.s V_5 + IL_0074: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" + IL_0079: stind.i4 + IL_007a: ldloc.3 + IL_007b: ldc.i4.1 + IL_007c: add + IL_007d: stloc.3 + IL_007e: ldloca.s V_4 + IL_0080: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0085: brtrue.s IL_0027 + IL_0087: leave.s IL_0097 + } + finally + { + IL_0089: ldloca.s V_4 + IL_008b: constrained. "System.Collections.Generic.List.Enumerator" + IL_0091: callvirt "void System.IDisposable.Dispose()" + IL_0096: endfinally + } + IL_0097: ldloc.1 + IL_0098: ret + } + """); + } + [Fact] public void ListConstruction_Dynamic_02() { @@ -18062,21 +18388,30 @@ static void Main() Diagnostic(ErrorCode.ERR_NoImplicitConv, "e").WithArguments("object", "int").WithLocation(4, 42)); } - [Fact(Skip = "// PROTOTYPE(ParamsCollections): Adjust for new dynamic behavior")] - public void ListConstruction_Dynamic_04() + [Fact] + public void ListConstruction_Dynamic_04_DynamicBinding() { string source = $$""" using System.Collections.Generic; class Program { - static List F1(dynamic d) => [d]; - static List F2(dynamic d) => [d]; + static MyList F1(dynamic d) => [d]; + static MyList F2(dynamic d) => [d]; static void Main() { F1(1).Report(); F2(2).Report(); } } + + namespace System.Collections.Generic + { + class MyList : List + { + public new void Add(T x) => base.Add(x); + public void Add(string x) => throw null; + } + } """; var verifier = CompileAndVerify( new[] { source, s_collectionExtensions }, @@ -18089,10 +18424,10 @@ static void Main() { // Code size 99 (0x63) .maxstack 9 - .locals init (System.Collections.Generic.List V_0) - IL_0000: newobj "System.Collections.Generic.List..ctor()" + .locals init (System.Collections.Generic.MyList V_0) + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" IL_0005: stloc.0 - IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_000b: brtrue.s IL_004b IL_000d: ldc.i4 0x100 IL_0012: ldstr "Add" @@ -18114,14 +18449,14 @@ .locals init (System.Collections.Generic.List V_0) IL_0036: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" IL_003b: stelem.ref IL_003c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" - IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" - IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" - IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" IL_005a: ldloc.0 IL_005b: ldarg.0 - IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" IL_0061: ldloc.0 IL_0062: ret } @@ -18131,10 +18466,10 @@ .locals init (System.Collections.Generic.List V_0) { // Code size 99 (0x63) .maxstack 9 - .locals init (System.Collections.Generic.List V_0) - IL_0000: newobj "System.Collections.Generic.List..ctor()" + .locals init (System.Collections.Generic.MyList V_0) + IL_0000: newobj "System.Collections.Generic.MyList..ctor()" IL_0005: stloc.0 - IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" IL_000b: brtrue.s IL_004b IL_000d: ldc.i4 0x100 IL_0012: ldstr "Add" @@ -18156,20 +18491,114 @@ .locals init (System.Collections.Generic.List V_0) IL_0036: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" IL_003b: stelem.ref IL_003c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" - IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" - IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" - IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" - IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" IL_005a: ldloc.0 IL_005b: ldarg.0 - IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.MyList, dynamic)" IL_0061: ldloc.0 IL_0062: ret } """); } + [Fact] + public void ListConstruction_Dynamic_04_StaticBinding() + { + string source = $$""" + using System.Collections.Generic; + class Program + { + static List F1(dynamic d) => [d]; + static List F2(dynamic d) => [d]; + static void Main() + { + F1(1).Report(); + F2(2).Report(); + } + } + """; + var verifier = CompileAndVerify( + new[] { source, s_collectionExtensions }, + targetFramework: TargetFramework.Net80, + options: TestOptions.ReleaseExe, + verify: Verification.FailsPEVerify, + expectedOutput: IncludeExpectedOutput("[1], [2], ")); + verifier.VerifyIL("Program.F1", + """ + { + // Code size 36 (0x24) + .maxstack 3 + .locals init (System.Span V_0, + int V_1) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_000c: dup + IL_000d: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: stloc.1 + IL_0015: ldloca.s V_0 + IL_0017: ldloc.1 + IL_0018: call "ref object System.Span.this[int].get" + IL_001d: ldarg.0 + IL_001e: stind.ref + IL_001f: ldloc.1 + IL_0020: ldc.i4.1 + IL_0021: add + IL_0022: stloc.1 + IL_0023: ret + } + """); + verifier.VerifyIL("Program.F2", + """ + { + // Code size 99 (0x63) + .maxstack 5 + .locals init (System.Span V_0, + int V_1) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: dup + IL_0006: ldc.i4.1 + IL_0007: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" + IL_000c: dup + IL_000d: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" + IL_0012: stloc.0 + IL_0013: ldc.i4.0 + IL_0014: stloc.1 + IL_0015: ldloca.s V_0 + IL_0017: ldloc.1 + IL_0018: call "ref int System.Span.this[int].get" + IL_001d: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0022: brtrue.s IL_0048 + IL_0024: ldc.i4.0 + IL_0025: ldtoken "int" + IL_002a: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_002f: ldtoken "Program" + IL_0034: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0039: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" + IL_003e: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0043: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0048: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_004d: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" + IL_0052: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" + IL_0057: ldarg.0 + IL_0058: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" + IL_005d: stind.i4 + IL_005e: ldloc.1 + IL_005f: ldc.i4.1 + IL_0060: add + IL_0061: stloc.1 + IL_0062: ret + } + """); + } + [Fact] public void ListConstruction_Dynamic_05() {