/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenMethodGroupConversionCachingTests.cs
6 879 строк
183 KB
Jason Malinowski
Remove AssertEx.NotNull
21 апр 2026, 23:28
21 апр 2026, 23:28
4c5adf0
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen; public class CodeGenMethodGroupConversionCachingTests : CSharpTestBase { const string PASS = "PASS"; [Fact] public void Not_DelegateCreations_Static() { var source = @" using System; delegate void D(); class C { public static void Main(string[] args) { Invoke(new D(Target), new D(Target)); } static void Target() { Console.WriteLine(""FAIL""); } static void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } }"; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 30 (0x1e) .maxstack 3 IL_0000: ldnull IL_0001: ldftn ""void C.Target()"" IL_0007: newobj ""D..ctor(object, System.IntPtr)"" IL_000c: ldnull IL_000d: ldftn ""void C.Target()"" IL_0013: newobj ""D..ctor(object, System.IntPtr)"" IL_0018: call ""void C.Invoke(D, D)"" IL_001d: ret } "); } [Fact] public void Not_DelegateCreations_Instance() { var source = @" using System; delegate void D(); class C { public static void Main(string[] args) { var c = new C(); c.Invoke(new D(c.Target), new D(c.Target)); } void Target() { Console.WriteLine(""FAIL""); } void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } }"; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 37 (0x25) .maxstack 4 .locals init (C V_0) //c IL_0000: newobj ""C..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 IL_0008: ldftn ""void C.Target()"" IL_000e: newobj ""D..ctor(object, System.IntPtr)"" IL_0013: ldloc.0 IL_0014: ldftn ""void C.Target()"" IL_001a: newobj ""D..ctor(object, System.IntPtr)"" IL_001f: callvirt ""void C.Invoke(D, D)"" IL_0024: ret } "); } [Fact] public void Not_Conversions_Instance() { var source = @" using System; delegate void D(); class C { public static void Main(string[] args) { var c = new C(); c.Invoke(c.Target, c.Target); } void Target() { Console.WriteLine(""FAIL""); } void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } }"; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 37 (0x25) .maxstack 4 .locals init (C V_0) //c IL_0000: newobj ""C..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 IL_0008: ldftn ""void C.Target()"" IL_000e: newobj ""D..ctor(object, System.IntPtr)"" IL_0013: ldloc.0 IL_0014: ldftn ""void C.Target()"" IL_001a: newobj ""D..ctor(object, System.IntPtr)"" IL_001f: callvirt ""void C.Invoke(D, D)"" IL_0024: ret } "); } [Fact] public void Not_DelegateCreations_InstanceExtensionMethod() { var source = @" using System; delegate void D(); class C { public static void Main(string[] args) { var c = new C(); c.Invoke(new D(c.Target), new D(c.Target)); } void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } } static class E { public static void Target(this C that) { Console.WriteLine(""FAIL""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 37 (0x25) .maxstack 4 .locals init (C V_0) //c IL_0000: newobj ""C..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 IL_0008: ldftn ""void E.Target(C)"" IL_000e: newobj ""D..ctor(object, System.IntPtr)"" IL_0013: ldloc.0 IL_0014: ldftn ""void E.Target(C)"" IL_001a: newobj ""D..ctor(object, System.IntPtr)"" IL_001f: callvirt ""void C.Invoke(D, D)"" IL_0024: ret } "); } [Fact] public void Not_Conversions_InstanceExtensionMethod() { var source = @" using System; delegate void D(); class C { public static void Main(string[] args) { var c = new C(); c.Invoke(c.Target, c.Target); } void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } } static class E { public static void Target(this C that) { Console.WriteLine(""FAIL""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 37 (0x25) .maxstack 4 .locals init (C V_0) //c IL_0000: newobj ""C..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 IL_0008: ldftn ""void E.Target(C)"" IL_000e: newobj ""D..ctor(object, System.IntPtr)"" IL_0013: ldloc.0 IL_0014: ldftn ""void E.Target(C)"" IL_001a: newobj ""D..ctor(object, System.IntPtr)"" IL_001f: callvirt ""void C.Invoke(D, D)"" IL_0024: ret } "); } [Fact] public void Not_DelegateCreations_StaticExtensionMethod() { var source = @" using System; delegate void D(C arg); class C { public static void Main(string[] args) { var c = new C(); c.Invoke(new D(E.Target), new D(E.Target)); } void Invoke(D x, D y) { Console.Write(Object.ReferenceEquals(x, y) ? ""FAIL"" : ""PASS""); } } static class E { public static void Target(this C that) { Console.WriteLine(""FAIL""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 35 (0x23) .maxstack 4 IL_0000: newobj ""C..ctor()"" IL_0005: ldnull IL_0006: ldftn ""void E.Target(C)"" IL_000c: newobj ""D..ctor(object, System.IntPtr)"" IL_0011: ldnull IL_0012: ldftn ""void E.Target(C)"" IL_0018: newobj ""D..ctor(object, System.IntPtr)"" IL_001d: callvirt ""void C.Invoke(D, D)"" IL_0022: ret } "); } [Fact] public void Not_InExpressionLambda0() { var source = @" using System; using System.Linq.Expressions; class C { public static void Main(string[] args) { Expression<Func<int, Func<int, int>>> e = x => Target; Console.WriteLine(e); } static int Target(int x) => 0; } "; var verifier = CompileAndVerify(source #if NETFRAMEWORK , expectedOutput: "x => Convert(Int32 Target(Int32).CreateDelegate(System.Func`2[System.Int32,System.Int32], null))" #else , expectedOutput: "x => Convert(Int32 Target(Int32).CreateDelegate(System.Func`2[System.Int32,System.Int32], null), Func`2)" #endif , symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.Main", @" { // Code size 160 (0xa0) .maxstack 7 .locals init (System.Linq.Expressions.ParameterExpression V_0) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" IL_000f: call ""System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"" IL_0014: stloc.0 IL_0015: ldtoken ""int C.Target(int)"" IL_001a: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" IL_001f: castclass ""System.Reflection.MethodInfo"" IL_0024: ldtoken ""System.Reflection.MethodInfo"" IL_0029: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_002e: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0033: ldtoken ""System.Delegate System.Reflection.MethodInfo.CreateDelegate(System.Type, object)"" IL_0038: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" IL_003d: castclass ""System.Reflection.MethodInfo"" IL_0042: ldc.i4.2 IL_0043: newarr ""System.Linq.Expressions.Expression"" IL_0048: dup IL_0049: ldc.i4.0 IL_004a: ldtoken ""System.Func<int, int>"" IL_004f: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0054: ldtoken ""System.Type"" IL_0059: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_005e: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0063: stelem.ref IL_0064: dup IL_0065: ldc.i4.1 IL_0066: ldnull IL_0067: ldtoken ""object"" IL_006c: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0071: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0076: stelem.ref IL_0077: call ""System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"" IL_007c: ldtoken ""System.Func<int, int>"" IL_0081: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0086: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" IL_008b: ldc.i4.1 IL_008c: newarr ""System.Linq.Expressions.ParameterExpression"" IL_0091: dup IL_0092: ldc.i4.0 IL_0093: ldloc.0 IL_0094: stelem.ref IL_0095: call ""System.Linq.Expressions.Expression<System.Func<int, System.Func<int, int>>> System.Linq.Expressions.Expression.Lambda<System.Func<int, System.Func<int, int>>>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"" IL_009a: call ""void System.Console.WriteLine(object)"" IL_009f: ret } "); } [Fact] public void Not_InExpressionLambda1() { var source = @" using System; using System.Linq.Expressions; class C { public static void Main(string[] args) { Func<int, Expression<Func<int, Func<int, int>>>> f = x => y => Target; Console.WriteLine(f(0)); } static int Target(int x) => 0; } "; var verifier = CompileAndVerify(source #if NETFRAMEWORK , expectedOutput: "y => Convert(Int32 Target(Int32).CreateDelegate(System.Func`2[System.Int32,System.Int32], null))" #else , expectedOutput: "y => Convert(Int32 Target(Int32).CreateDelegate(System.Func`2[System.Int32,System.Int32], null), Func`2)" #endif , symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C.<>c.<Main>b__0_0", @" { // Code size 155 (0x9b) .maxstack 7 .locals init (System.Linq.Expressions.ParameterExpression V_0) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""y"" IL_000f: call ""System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"" IL_0014: stloc.0 IL_0015: ldtoken ""int C.Target(int)"" IL_001a: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" IL_001f: castclass ""System.Reflection.MethodInfo"" IL_0024: ldtoken ""System.Reflection.MethodInfo"" IL_0029: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_002e: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0033: ldtoken ""System.Delegate System.Reflection.MethodInfo.CreateDelegate(System.Type, object)"" IL_0038: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" IL_003d: castclass ""System.Reflection.MethodInfo"" IL_0042: ldc.i4.2 IL_0043: newarr ""System.Linq.Expressions.Expression"" IL_0048: dup IL_0049: ldc.i4.0 IL_004a: ldtoken ""System.Func<int, int>"" IL_004f: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0054: ldtoken ""System.Type"" IL_0059: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_005e: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0063: stelem.ref IL_0064: dup IL_0065: ldc.i4.1 IL_0066: ldnull IL_0067: ldtoken ""object"" IL_006c: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0071: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" IL_0076: stelem.ref IL_0077: call ""System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"" IL_007c: ldtoken ""System.Func<int, int>"" IL_0081: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0086: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" IL_008b: ldc.i4.1 IL_008c: newarr ""System.Linq.Expressions.ParameterExpression"" IL_0091: dup IL_0092: ldc.i4.0 IL_0093: ldloc.0 IL_0094: stelem.ref IL_0095: call ""System.Linq.Expressions.Expression<System.Func<int, System.Func<int, int>>> System.Linq.Expressions.Expression.Lambda<System.Func<int, System.Func<int, int>>>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"" IL_009a: ret } "); } [Fact] public void Not_InStaticConstructor0() { var source = @" using System; class C { static readonly Action ManualCache = Target; static void Target() { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C..cctor", @" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""void C.Target()"" IL_0007: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000c: stsfld ""System.Action C.ManualCache"" IL_0011: ret } "); } [Fact] public void Not_InStaticConstructor1() { var source = @" using System; struct C { static readonly Action ManualCache; static void Target() { } static C() { ManualCache = Target; } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyNoCacheContainersIn("C")); verifier.VerifyIL("C..cctor", @" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""void C.Target()"" IL_0007: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000c: stsfld ""System.Action C.ManualCache"" IL_0011: ret } "); } [Fact] public void Not_TargetTypedNew0() { var source = @" using System; Action f = new(Target); f(); static void Target() { Console.WriteLine(""PASS""); } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("Program")); verifier.VerifyIL("<top-level-statements-entry-point>", @" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""void Program.<<Main>$>g__Target|0_0()"" IL_0007: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000c: callvirt ""void System.Action.Invoke()"" IL_0011: ret } "); } [Fact] public void Not_TargetTypedNew1() { var source = @" #nullable enable using System; Action? f = new(Target); f(); static void Target() { Console.WriteLine(""PASS""); } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyNoCacheContainersIn("Program")); verifier.VerifyIL("<top-level-statements-entry-point>", @" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""void Program.<<Main>$>g__Target|0_0()"" IL_0007: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000c: callvirt ""void System.Action.Invoke()"" IL_0011: ret } "); } [Fact] public void Not_CSharp10() { var source = @" var f = Target; f(); static void Target() { } "; var verifier = CompileAndVerify(source, parseOptions: TestOptions.Regular10, symbolValidator: VerifyNoCacheContainersIn("Program")); verifier.VerifyIL("<top-level-statements-entry-point>", @" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""void Program.<<Main>$>g__Target|0_0()"" IL_0007: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000c: callvirt ""void System.Action.Invoke()"" IL_0011: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { public static void Main(string[] args) { Test((Action)Target); } static void Test(Action action) { action(); } static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.Main", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action C.<>O.<0>__Target"" IL_001b: call ""void C.Test(System.Action)"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped1() { var source = @" using System; class C { public static void Main(string[] args) { var d = new D<int>(); d.Test()(); } public static void Target() { Console.WriteLine(""PASS""); } } class D<T> { public Action Test() { return (Action)C.Target; } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)E<int>.Target; t(); } } class E<V> { public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<int>.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped3() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action<int>)E<int>.Target; t(0); } } class E<V> { public static void Target(V v) { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<int>.Target(int)"" IL_0010: newobj ""System.Action<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<int> D<T>.<>O.<0>__Target"" IL_001b: ldc.i4.0 IL_001c: callvirt ""void System.Action<int>.Invoke(int)"" IL_0021: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped4() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action<int>)E<int>.Target<double>; t(0); } } class E<V> { public static void Target<K>(V v) { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<int>.Target<double>(int)"" IL_0010: newobj ""System.Action<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<int> D<T>.<>O.<0>__Target"" IL_001b: ldc.i4.0 IL_001c: callvirt ""void System.Action<int>.Invoke(int)"" IL_0021: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped_CouldBeModuleScoped5() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Func<int, int>)E<int>.Target<double>; t(0); } } class E<V> { public static V Target<K>(V v) { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<int, int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int E<int>.Target<double>(int)"" IL_0010: newobj ""System.Func<int, int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int, int> D<T>.<>O.<0>__Target"" IL_001b: ldc.i4.0 IL_001c: callvirt ""int System.Func<int, int>.Invoke(int)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped0() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)Target; t(); } static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped1() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)Target<int>; t(); } static void Target<K>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target<int>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)Target<T>; t(); } static void Target<K>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target<T>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped3() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)E<T>.Target; t(); } } class E<V> { public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<T>.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped4() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Action)E<T>.Target<double>; t(); } } class E<V> { public static void Target<N>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<T>.Target<double>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped5() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Func<T>)E<int>.Target<T>; t(); } } class E<V> { public static N Target<N>() { Console.WriteLine(""PASS""); return default(N); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<T> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T E<int>.Target<T>()"" IL_0010: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""T System.Func<T>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped6() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Func<int>)E<T>.Target<int>; t(); } } class E<K> { public static V Target<V>() { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int E<T>.Target<int>()"" IL_0010: newobj ""System.Func<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""int System.Func<int>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void CacheExplicitConversions_TypeScoped7() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { var t = (Func<T, int>)E<T>.Target<int>; t(default(T)); } } class E<K> { public static V Target<V>(K k) { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Func<T, int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int E<T>.Target<int>(T)"" IL_0010: newobj ""System.Func<T, int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, int> D<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""int System.Func<T, int>.Invoke(T)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void CacheExplicitConversions_MethodScoped0() { var source = @" using System; class C { public static void Main(string[] args) { D.Test<int>(); } public static void Target<K>() { Console.WriteLine(""PASS""); } } class D { public static void Test<T>() { var t = (Action)C.Target<T>; t(); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D.Test<T>", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target<T>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D.<Test>O__0_0<T>.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_MethodScoped1() { var source = @" using System; class C { public static void Main(string[] args) { (new D()).Test<int>(); } } class D { public void Test<T>() { var t = (Action)E<T>.Target; t(); } } class E<K> { public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D.Test<T>", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action D.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<T>.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action D.<Test>O__0_0<T>.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheExplicitConversions_MethodScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D()).Test<int>(); } } class D { public void Test<T>() { var t = (Func<T, int>)E<T>.Target<int>; t(default(T)); } } class E<K> { public static V Target<V>(K k) { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D.Test<T>", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Func<T, int> D.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int E<T>.Target<int>(T)"" IL_0010: newobj ""System.Func<T, int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, int> D.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""int System.Func<T, int>.Invoke(T)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void CacheExplicitConversions_MethodScoped3() { var source = @" using System; class C { public static void Main(string[] args) { (new D<long>()).Test<int>(); } } class D<M> { public void Test<T>() { var t = (Action<M, T>)E<M>.Target<T>; t(default(M), default(T)); } } class E<K> { public static void Target<V>(K k, V v) { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<M>.Test<T>", @" { // Code size 51 (0x33) .maxstack 3 .locals init (M V_0, T V_1) IL_0000: ldsfld ""System.Action<M, T> D<M>.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<M>.Target<T>(M, T)"" IL_0010: newobj ""System.Action<M, T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<M, T> D<M>.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""M"" IL_0023: ldloc.0 IL_0024: ldloca.s V_1 IL_0026: initobj ""T"" IL_002c: ldloc.1 IL_002d: callvirt ""void System.Action<M, T>.Invoke(M, T)"" IL_0032: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; delegate void MyAction<T>(); class C { public static void Main(string[] args) { MyAction<int> t = Target; t(); } static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.Main", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""MyAction<int> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""MyAction<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""MyAction<int> C.<>O.<0>__Target"" IL_001b: callvirt ""void MyAction<int>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped_CouldBeModuleScoped1() { var source = @" using System; class C { public delegate void MyAction<T>(); public static void Main(string[] args) { MyAction<int> t = Target; t(); } static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.Main", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""C.MyAction<int> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""C.MyAction<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""C.MyAction<int> C.<>O.<0>__Target"" IL_001b: callvirt ""void C.MyAction<int>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped0() { var source = @" using System; delegate void MyAction(); class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { public void Test() { MyAction t = Target; t(); } public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""MyAction D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target()"" IL_0010: newobj ""MyAction..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""MyAction D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void MyAction.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped1() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test()(); } } class D<T> { public delegate void MyAction(); public MyAction Test() { return Target<int>; } static void Target<K>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldsfld ""D<T>.MyAction D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target<int>()"" IL_0010: newobj ""D<T>.MyAction..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyAction D<T>.<>O.<0>__Target"" IL_001b: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { delegate void MyAction<M>(); public void Test() { MyAction<int> t = Target<T>; t(); } static void Target<K>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""D<T>.MyAction<int> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.Target<T>()"" IL_0010: newobj ""D<T>.MyAction<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyAction<int> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void D<T>.MyAction<int>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped3() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { delegate void MyAction<M>(); public void Test() { MyAction<T> t = E<T>.Target; t(); } } class E<V> { public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""D<T>.MyAction<T> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<T>.Target()"" IL_0010: newobj ""D<T>.MyAction<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyAction<T> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void D<T>.MyAction<T>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped4() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { delegate void MyAction<M>(); public void Test() { MyAction<T> t = E<T>.Target<int>; t(); } } class E<V> { public static void Target<N>() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""D<T>.MyAction<T> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<T>.Target<int>()"" IL_0010: newobj ""D<T>.MyAction<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyAction<T> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""void D<T>.MyAction<T>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped5() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { delegate T MyFunc(); public void Test() { MyFunc t = E<T>.Target<T, int>; t(); } } class E<K> { public static V Target<V, K>() { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T E<T>.Target<T, int>()"" IL_0010: newobj ""D<T>.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_001b: callvirt ""T D<T>.MyFunc.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped6() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test(); } } class D<T> { delegate int MyFunc(T i); public void Test() { MyFunc t = E<T>.Target<int>; t(default(T)); } } class E<K> { public static V Target<V>(K k) { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int E<T>.Target<int>(T)"" IL_0010: newobj ""D<T>.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""int D<T>.MyFunc.Invoke(T)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped7() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int, double>()).Test(); } } class D<T, M> { delegate T MyFunc(M m); public void Test() { MyFunc t = E<M>.Target<T>; t(default(M)); } } class E<K> { public static V Target<V>(K k) { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T, M>.Test", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (M V_0) IL_0000: ldsfld ""D<T, M>.MyFunc D<T, M>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T E<M>.Target<T>(M)"" IL_0010: newobj ""D<T, M>.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T, M>.MyFunc D<T, M>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""M"" IL_0023: ldloc.0 IL_0024: callvirt ""T D<T, M>.MyFunc.Invoke(M)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void CacheImplicitConversions_TypeScoped8() { var source = @" using System; class C { delegate void MyAction<T>(); public static void Main(string[] args) { MyAction<int> t = Target; t(); } static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.Main", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""C.MyAction<int> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""C.MyAction<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""C.MyAction<int> C.<>O.<0>__Target"" IL_001b: callvirt ""void C.MyAction<int>.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_MethodScoped0() { var source = @" using System; class C { public static void Main(string[] args) { (new D()).Test<int>(); } public static void Target<K>() { Console.WriteLine(""PASS""); } } class D { delegate void MyAction(); public void Test<T>() { MyAction t = C.Target<T>; t(); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D.Test<T>", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""D.MyAction D.<Test>O__1_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target<T>()"" IL_0010: newobj ""D.MyAction..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D.MyAction D.<Test>O__1_0<T>.<0>__Target"" IL_001b: callvirt ""void D.MyAction.Invoke()"" IL_0020: ret } "); } [Fact] public void CacheImplicitConversions_MethodScoped1() { var source = @" using System; class C { public static void Main(string[] args) { (new D<int>()).Test<int>(); } public static void Target<K, N>(K k) { Console.WriteLine(""PASS""); } } class D<V> { delegate void MyAction<M>(M m); public void Test<T>() { MyAction<V> t = C.Target<V, T>; t(default(V)); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<V>.Test<T>", @" { // Code size 42 (0x2a) .maxstack 2 .locals init (V V_0) IL_0000: ldsfld ""D<V>.MyAction<V> D<V>.<Test>O__1_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target<V, T>(V)"" IL_0010: newobj ""D<V>.MyAction<V>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<V>.MyAction<V> D<V>.<Test>O__1_0<T>.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""V"" IL_0023: ldloc.0 IL_0024: callvirt ""void D<V>.MyAction<V>.Invoke(V)"" IL_0029: ret } "); } [Fact] public void CacheImplicitConversions_MethodScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D<byte>()).Test<int>(); } public static N Target<K, N>(K k, N n) { Console.WriteLine(""PASS""); return default(N); } } class D<V> { delegate V MyFunc<M>(M m, V v); public void Test<T>() { MyFunc<T> t = C.Target<T, V>; t(default(T), default(V)); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<V>.Test<T>", @" { // Code size 52 (0x34) .maxstack 3 .locals init (T V_0, V V_1) IL_0000: ldsfld ""D<V>.MyFunc<T> D<V>.<Test>O__1_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""V C.Target<T, V>(T, V)"" IL_0010: newobj ""D<V>.MyFunc<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<V>.MyFunc<T> D<V>.<Test>O__1_0<T>.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: ldloca.s V_1 IL_0026: initobj ""V"" IL_002c: ldloc.1 IL_002d: callvirt ""V D<V>.MyFunc<T>.Invoke(T, V)"" IL_0032: pop IL_0033: ret } "); } [Fact] public void Where_TypeScoped0() { var source = @" using System; class C { public static void Main(string[] args) { (new D<C>()).Test(); } } class D<T> where T : C { delegate void MyAction(T t); public void Test() { MyAction t = E<int>.Target<C>; t(null); } } class E<V> { public static void Target<N>(N n) { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.Test", @" { // Code size 42 (0x2a) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""D<T>.MyAction D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E<int>.Target<C>(C)"" IL_0010: newobj ""D<T>.MyAction..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyAction D<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""void D<T>.MyAction.Invoke(T)"" IL_0029: ret } "); } [Fact] public void Where_MethodScoped0() { var source = @" using System; class C { public static void Main(string[] args) { (new D<C>()).Test(new C()); } } class D<T> where T : C { delegate T MyFunc(); public void Test<M>(M m) where M : T { MyFunc t = E<int>.Target<M>; t(); } } class E<V> { public static N Target<N>() { Console.WriteLine(""PASS""); return default(N); } } "; static void containerValidator(ModuleSymbol module) { var testClass = module.GlobalNamespace.GetTypeMember("D"); var container = testClass.GetTypeMember("<Test>O__1_0"); Assert.NotNull(container); var typeParameters = container.TypeParameters; Assert.Equal(1, container.TypeParameters.Length); var m = typeParameters[0]; Assert.Equal(1, m.ConstraintTypes().Length); Assert.Equal(testClass.TypeParameters[0], m.ConstraintTypes()[0]); } CompileAndVerify(source, symbolValidator: containerValidator, expectedOutput: PASS).VerifyIL("D<T>.Test<M>", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""D<T>.MyFunc D<T>.<Test>O__1_0<M>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""M E<int>.Target<M>()"" IL_0010: newobj ""D<T>.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyFunc D<T>.<Test>O__1_0<M>.<0>__Target"" IL_001b: callvirt ""T D<T>.MyFunc.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Where_MethodScoped1() { var source = @" using System; class C { public static void Main(string[] args) { (new D()).Test(new C()); } } class D { delegate C MyFunc(); public void Test<M>(M m) where M : C { MyFunc t = E<int>.Target<M>; t(); } } class E<V> { public static N Target<N>() { Console.WriteLine(""PASS""); return default(N); } } "; static void containerValidator(ModuleSymbol module) { var globalNs = module.GlobalNamespace; var mainClass = globalNs.GetTypeMember("C"); var container = globalNs.GetMember<NamedTypeSymbol>("D.<Test>O__1_0"); Assert.NotNull(container); var typeParameters = container.TypeParameters; Assert.Equal(1, container.TypeParameters.Length); var m = typeParameters[0]; Assert.Equal(1, m.ConstraintTypes().Length); Assert.Equal(mainClass, m.ConstraintTypes()[0]); } CompileAndVerify(source, symbolValidator: containerValidator, expectedOutput: PASS).VerifyIL("D.Test<M>", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""D.MyFunc D.<Test>O__1_0<M>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""M E<int>.Target<M>()"" IL_0010: newobj ""D.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D.MyFunc D.<Test>O__1_0<M>.<0>__Target"" IL_001b: callvirt ""C D.MyFunc.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Where_MethodScoped2() { var source = @" using System; class C { public static void Main(string[] args) { (new D()).Test(0); } } class D { public void Test<M>(M m) where M : struct { Func<M?> t = E.Target<M?>; t(); } } class E { public static N Target<N>() { Console.WriteLine(""PASS""); return default(N); } } "; static void containerValidator(ModuleSymbol module) { var container = module.GlobalNamespace.GetMember<NamedTypeSymbol>("D.<Test>O__0_0"); Assert.NotNull(container); var typeParameters = container.TypeParameters; Assert.Equal(1, container.TypeParameters.Length); var m = typeParameters[0]; Assert.NotNull(m); Assert.True(m.IsValueType); } CompileAndVerify(source, symbolValidator: containerValidator, expectedOutput: PASS).VerifyIL("D.Test<M>", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<M?> D.<Test>O__0_0<M>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""M? E.Target<M?>()"" IL_0010: newobj ""System.Func<M?>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<M?> D.<Test>O__0_0<M>.<0>__Target"" IL_001b: callvirt ""M? System.Func<M?>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void ExtensionMethod_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { public static void Main(string[] args) { var t = (Action<C>)E.Target; t(null); } } static class E { public static void Target(this C c) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("C.Main", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<C> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target(C)"" IL_0010: newobj ""System.Action<C>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<C> C.<>O.<0>__Target"" IL_001b: ldnull IL_001c: callvirt ""void System.Action<C>.Invoke(C)"" IL_0021: ret } "); } [Fact] public void ExtensionMethod_TypeScoped_CouldBeModuleScoped1() { var source = @" using System; class C { public static void Main(string[] args) { Action<C> t = E.Target; t(null); } } static class E { public static void Target<T>(this T t) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("C.Main", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<C> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target<C>(C)"" IL_0010: newobj ""System.Action<C>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<C> C.<>O.<0>__Target"" IL_001b: ldnull IL_001c: callvirt ""void System.Action<C>.Invoke(C)"" IL_0021: ret } "); } [Fact] public void ExtensionMethod_TypeScoped_CouldBeModuleScoped2() { var source = @" using System; static class E { static void Test() { Action<int> t = Target<int>; } public static void Target<T>(this T t) { } } "; CompileAndVerify(source).VerifyIL("E.Test", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<int> E.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E.Target<int>(int)"" IL_000e: newobj ""System.Action<int>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<int> E.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void ExtensionMethod_TypeScoped0() { var source = @" using System; class C { public static void Main(string[] args) { D<C>.Test(); } } class D<T> where T : C { public static void Test() { var t = (Action<T>)E.Target; t(null); } } static class E { public static void Target(this C c) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("D<T>.Test", @" { // Code size 42 (0x2a) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Action<T> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target(C)"" IL_0010: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<T> D<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""void System.Action<T>.Invoke(T)"" IL_0029: ret } "); } [Fact] public void ExtensionMethod_TypeScoped1() { var source = @" using System; class C { public static void Main(string[] args) { D<int>.Test(0); } } class D<K> { public static void Test(K k) { Action<K> t = E.Target; t(k); } } static class E { public static void Target<T>(this T t) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("D<K>.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<K> D<K>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target<K>(K)"" IL_0010: newobj ""System.Action<K>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<K> D<K>.<>O.<0>__Target"" IL_001b: ldarg.0 IL_001c: callvirt ""void System.Action<K>.Invoke(K)"" IL_0021: ret } "); } [Fact] public void ExtensionMethod_TypeScoped2() { var source = @" using System; static class E { class F<T> { void Test() { Action<T> t = Target<T>; } } public static void Target<T>(this T t) { } } "; CompileAndVerify(source).VerifyIL("E.F<T>.Test", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<T> E.F<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E.Target<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> E.F<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void ExtensionMethod_MethodScoped0() { var source = @" using System; class C { public static void Main(string[] args) { Test(0); } static void Test<T>(T arg) { var t = (Action<T>)E.Target; t(arg); } } static class E { public static void Target<M>(this M m) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("C.Test<T>", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Action<T> C.<Test>O__1_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target<T>(T)"" IL_0010: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<T> C.<Test>O__1_0<T>.<0>__Target"" IL_001b: ldarg.0 IL_001c: callvirt ""void System.Action<T>.Invoke(T)"" IL_0021: ret } "); } [Fact] public void ExtensionMethod_MethodScoped1() { var source = @" using System; class C { public static void Main(string[] args) { Test<C>(); } static void Test<T>() where T : C { var t = (Action<T>)E.Target; t(null); } } static class E { public static void Target(this C c) { Console.WriteLine(""PASS""); } } "; CompileAndVerify(source, expectedOutput: PASS).VerifyIL("C.Test<T>", @" { // Code size 42 (0x2a) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Action<T> C.<Test>O__1_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.Target(C)"" IL_0010: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action<T> C.<Test>O__1_0<T>.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""void System.Action<T>.Invoke(T)"" IL_0029: ret } "); } [Fact] public void ExtensionMethod_MethodScoped2() { var source = @" using System; static class E { static void Test<T>() { Action<T> t = Target<T>; } public static void Target<T>(this T t) { } } "; CompileAndVerify(source).VerifyIL("E.Test<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E.Target<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0018: ret } "); } [Fact] public void Lambda_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { public static void Main(string[] args) { Action test = () => Invoke(Target); test(); } static void Invoke(Action a) => a(); static void Target() => Console.WriteLine(""PASS""); } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.<>c.<Main>b__0_0", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void C.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action C.<>O.<0>__Target"" IL_001b: call ""void C.Invoke(System.Action)"" IL_0020: ret } "); } [Fact] public void Lambda_TypeScoped_CouldBeModuleScoped1() { var source = @" using System; class C { public static void Main(string[] args) { Action test = () => ((Action)D.Target)(); test(); } } class D { public static void Target() { Console.WriteLine(""PASS""); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("C.<>c.<Main>b__0_0", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D.Target()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action C.<>O.<0>__Target"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void Lambda_TypeScoped0() { var source = @" using System; class C { static void Main(string[] args) { D<int>.Test(); } } class D<T> { public static void Test() { Action test = () => { ((Func<T>)Target)(); }; test(); } static T Target() { Console.WriteLine(""PASS""); return default(T); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.<>c.<Test>b__0_0", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<T> D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T D<T>.Target()"" IL_0010: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T> D<T>.<>O.<0>__Target"" IL_001b: callvirt ""T System.Func<T>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Lambda_TypeScoped1() { var source = @" using System; class C { static void Main(string[] args) { D<int>.Test(); } } class D<T> { delegate T MyFunc(); public static void Test() { Func<MyFunc> a = () => E.Target<T>; a()(); } } class E { public static V Target<V>() { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.<>c.<Test>b__1_0", @" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T E.Target<T>()"" IL_0010: newobj ""D<T>.MyFunc..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D<T>.MyFunc D<T>.<>O.<0>__Target"" IL_001b: ret } "); } [Fact] public void Lambda_MethodScoped0() { var source = @" using System; class C { static void Main(string[] args) { D<int>.Test(0); } } class D<T> { public static void Test<G>(G g) { Action test = () => { ((Func<T>)Target<G>)(); }; test(); } static T Target<K>() { Console.WriteLine(""PASS""); return default(T); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D<T>.<>c__0<G>.<Test>b__0_0", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<T> D<T>.<Test>O__0_0<G>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""T D<T>.Target<G>()"" IL_0010: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T> D<T>.<Test>O__0_0<G>.<0>__Target"" IL_001b: callvirt ""T System.Func<T>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Lambda_MethodScoped1() { var source = @" using System; class C { static void Main(string[] args) { D.Test(0); } } class D { public static void Test<G>(G g) { Func<Func<G>> a = () => E<G>.Target; a()(); } } class E<V> { public static V Target() { Console.WriteLine(""PASS""); return default(V); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS); verifier.VerifyIL("D.<>c__0<G>.<Test>b__0_0", @" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldsfld ""System.Func<G> D.<Test>O__0_0<G>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""G E<G>.Target()"" IL_0010: newobj ""System.Func<G>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<G> D.<Test>O__0_0<G>.<0>__Target"" IL_001b: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped0() { var source = @" using System; class C<T> { void Test0() { var t = (Action)D.Target<T>; } void Test1() { Action t = D.Target<T>; } } class D { public static void Target<V>() { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "System.Action <0>__Target" )); verifier.VerifyIL("C<T>.Test0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C<T>.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C<T>.Test1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped1() { var source = @" using System; class C<T> { void Test0() { var t = (Func<T>)Target<T>; } void Test1() { Func<T> t = Target<T>; } static V Target<V>() { return default(V); } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "System.Func<T> <0>__Target" )); verifier.VerifyIL("C<T>.Test0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T>.Target<T>()"" IL_000e: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C<T>.Test1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T>.Target<T>()"" IL_000e: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped2() { var source = @" using System; class C<T, V> { delegate T MyFunc(); void Test0() { var t = (MyFunc)Target; } void Test1() { MyFunc t = Target; } static T Target() { return default(T); } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "C<T, V>.MyFunc <0>__Target" )); verifier.VerifyIL("C<T, V>.Test0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""C<T, V>.MyFunc C<T, V>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T, V>.Target()"" IL_000e: newobj ""C<T, V>.MyFunc..ctor(object, System.IntPtr)"" IL_0013: stsfld ""C<T, V>.MyFunc C<T, V>.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C<T, V>.Test1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""C<T, V>.MyFunc C<T, V>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T, V>.Target()"" IL_000e: newobj ""C<T, V>.MyFunc..ctor(object, System.IntPtr)"" IL_0013: stsfld ""C<T, V>.MyFunc C<T, V>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped3_CLRSignature() { var source = @" #nullable enable using System; class C<T> { void Test0() { var t = (Func<T?>)Target<T?>; } void Test1() { Func<T> t = Target<T>; } static V Target<V>() { return default(V); } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "System.Func<T?> <0>__Target" )); verifier.VerifyIL("C<T>.Test0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T>.Target<T>()"" IL_000e: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C<T>.Test1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""T C<T>.Target<T>()"" IL_000e: newobj ""System.Func<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T> C<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped4_CLRSignature() { var source = @" using System; class C<T> { void Test0() { var t = (Func<(T x, T y)>)Target<(T x, T y)>; } void Test1() { Func<(T a, T b)> t = Target<(T c, T d)>; } static V Target<V>() { return default(V); } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "System.Func<(T x, T y)> <0>__Target" )); verifier.VerifyIL("C<T>.Test0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<T, T> C<T>.Target<System.ValueTuple<T, T>>()"" IL_000e: newobj ""System.Func<System.ValueTuple<T, T>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C<T>.Test1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<T, T> C<T>.Target<System.ValueTuple<T, T>>()"" IL_000e: newobj ""System.Func<System.ValueTuple<T, T>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_TypeScoped5_AnonymousDelegate() { var source = @" class C { void Test0<T>(T t) { G0(Target<int>); } void Test1<T>(T t) { G1(Target<int>); } void G0(System.Delegate d) { } void G1(System.Delegate d) { } static dynamic Target<G>(ref G g) => 0; } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "<>F{00000001}<System.Int32, System.Object> <0>__Target" )); verifier.VerifyIL("C.Test0<T>", @" { // Code size 34 (0x22) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""dynamic C.Target<int>(ref int)"" IL_0011: newobj ""<>F{00000001}<int, dynamic>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_001c: call ""void C.G0(System.Delegate)"" IL_0021: ret } "); verifier.VerifyIL("C.Test1<T>", @" { // Code size 34 (0x22) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""dynamic C.Target<int>(ref int)"" IL_0011: newobj ""<>F{00000001}<int, dynamic>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_001c: call ""void C.G1(System.Delegate)"" IL_0021: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_MethodScoped0() { var source = @" using System; class C { void Test<V>() { var t0 = (Action)D.Target<V>; Action t1 = D.Target<V>; } } class D { public static void Target<B>() { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__0_0", arity: 1 , "System.Action <0>__Target" )); verifier.VerifyIL("C.Test<V>", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Test>O__0_0<V>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D.Target<V>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Test>O__0_0<V>.<0>__Target"" IL_0018: ldsfld ""System.Action C.<Test>O__0_0<V>.<0>__Target"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void D.Target<V>()"" IL_0026: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action C.<Test>O__0_0<V>.<0>__Target"" IL_0030: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_MethodScoped1() { var source = @" using System; class C<T> { void Test<V>() { var t0 = (Func<T, V>)D<V>.Target<T>; Func<T, V> t1 = D<V>.Target<T>; } } class D<B> { public static B Target<H>(H h) => default(B); } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__0_0", arity: 1 , "System.Func<T, V> <0>__Target" )); verifier.VerifyIL("C<T>.Test<V>", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Func<T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""V D<V>.Target<T>(T)"" IL_000e: newobj ""System.Func<T, V>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0018: ldsfld ""System.Func<T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""V D<V>.Target<T>(T)"" IL_0026: newobj ""System.Func<T, V>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Func<T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0030: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_MethodScoped2() { var source = @" using System; class C<A, T> { delegate O MyFunc(int num); class O { } void Test<V>() where V : O { var t0 = (MyFunc)D.Target<V>; MyFunc t1 = D.Target<V>; } } static class D { public static B Target<B>(this int num) => default(B); } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__2_0", arity: 1 , "C<A, T>.MyFunc <0>__Target" )); verifier.VerifyIL("C<A, T>.Test<V>", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""C<A, T>.MyFunc C<A, T>.<Test>O__2_0<V>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""V D.Target<V>(int)"" IL_000e: newobj ""C<A, T>.MyFunc..ctor(object, System.IntPtr)"" IL_0013: stsfld ""C<A, T>.MyFunc C<A, T>.<Test>O__2_0<V>.<0>__Target"" IL_0018: ldsfld ""C<A, T>.MyFunc C<A, T>.<Test>O__2_0<V>.<0>__Target"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""V D.Target<V>(int)"" IL_0026: newobj ""C<A, T>.MyFunc..ctor(object, System.IntPtr)"" IL_002b: stsfld ""C<A, T>.MyFunc C<A, T>.<Test>O__2_0<V>.<0>__Target"" IL_0030: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_MethodScoped3_CLRSignature() { var source = @" using System; class C<T> { void Test<V>() { var t0 = (Func<object, T, V>)D<V>.Target<T>; Func<dynamic, T, V> t1 = D<V>.Target<T>; } } class D<B> { public static B Target<H>(dynamic o, H h) => default(B); } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__0_0", arity: 1 , "System.Func<System.Object, T, V> <0>__Target" )); verifier.VerifyIL("C<T>.Test<V>", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Func<object, T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""V D<V>.Target<T>(dynamic, T)"" IL_000e: newobj ""System.Func<object, T, V>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<object, T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0018: ldsfld ""System.Func<object, T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""V D<V>.Target<T>(dynamic, T)"" IL_0026: newobj ""System.Func<dynamic, T, V>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Func<object, T, V> C<T>.<Test>O__0_0<V>.<0>__Target"" IL_0030: ret } "); } [Fact] public void SameTypeAndSymbolResultsSameField_MethodScoped4_AnonymousDelegate() { var source = @" class C { void Test<T>(T t) { G0(Target<T>); G1(Target<T>); } void G0(System.Delegate d) { } void G1(System.Delegate d) { } static dynamic Target<G>(ref G g) => 0; } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__0_0", arity: 1 , "<>F{00000001}<T, System.Object> <0>__Target" )); verifier.VerifyIL("C.Test<T>", @" { // Code size 67 (0x43) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""dynamic C.Target<T>(ref T)"" IL_0011: newobj ""<>F{00000001}<T, dynamic>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_001c: call ""void C.G0(System.Delegate)"" IL_0021: ldarg.0 IL_0022: ldsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_0027: dup IL_0028: brtrue.s IL_003d IL_002a: pop IL_002b: ldnull IL_002c: ldftn ""dynamic C.Target<T>(ref T)"" IL_0032: newobj ""<>F{00000001}<T, dynamic>..ctor(object, System.IntPtr)"" IL_0037: dup IL_0038: stsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_003d: call ""void C.G1(System.Delegate)"" IL_0042: ret } "); } [Fact] public void ContainersCanBeShared_TypeScoped0() { var source = @" using System; class A<T> { class B<V> { void Test0() { Action<T> t0 = Target0; Action<T> t1 = Target1; } void Test1() { Action<T> t1 = Target1; Action<T> t2 = D<T>.Target2; } void Test2() { Action<T> t2 = D<T>.Target2; Action<T, V> t3 = D<T>.Target3<V>; } void Test3() { Action<T, V> t3 = D<T>.Target3<V>; Action<T, V> t4 = D<T>.E<V>.Target4; } void Test4() { Action<T, V> t4 = D<T>.E<V>.Target4; Action<T> t5 = E.Target5<T>; } void Test5() { Action<T> t5t = E.Target5<T>; Action<V> t5v = E.Target5<V>; } static void Target0(T t) { } } static void Target1(T t) { } } class D<K> { public static void Target2(K k) { } public static void Target3<M>(K k, M m) { } public class E<P> { public static void Target4(K k, P p) { } } } static class E { public static void Target5<N>(this N n) { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("A.B.<>O", arity: 0 , "System.Action<T> <0>__Target0" , "System.Action<T> <1>__Target1" , "System.Action<T> <2>__Target2" , "System.Action<T, V> <3>__Target3" , "System.Action<T, V> <4>__Target4" , "System.Action<T> <5>__Target5" , "System.Action<V> <6>__Target5" )); verifier.VerifyIL("A<T>.B<V>.Test0", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<0>__Target0"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void A<T>.B<V>.Target0(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> A<T>.B<V>.<>O.<0>__Target0"" IL_0018: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<1>__Target1"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void A<T>.Target1(T)"" IL_0026: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T> A<T>.B<V>.<>O.<1>__Target1"" IL_0030: ret } "); verifier.VerifyIL("A<T>.B<V>.Test1", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<1>__Target1"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void A<T>.Target1(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> A<T>.B<V>.<>O.<1>__Target1"" IL_0018: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<2>__Target2"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void D<T>.Target2(T)"" IL_0026: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T> A<T>.B<V>.<>O.<2>__Target2"" IL_0030: ret } "); verifier.VerifyIL("A<T>.B<V>.Test2", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<2>__Target2"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D<T>.Target2(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> A<T>.B<V>.<>O.<2>__Target2"" IL_0018: ldsfld ""System.Action<T, V> A<T>.B<V>.<>O.<3>__Target3"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void D<T>.Target3<V>(T, V)"" IL_0026: newobj ""System.Action<T, V>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T, V> A<T>.B<V>.<>O.<3>__Target3"" IL_0030: ret } "); verifier.VerifyIL("A<T>.B<V>.Test3", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T, V> A<T>.B<V>.<>O.<3>__Target3"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D<T>.Target3<V>(T, V)"" IL_000e: newobj ""System.Action<T, V>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T, V> A<T>.B<V>.<>O.<3>__Target3"" IL_0018: ldsfld ""System.Action<T, V> A<T>.B<V>.<>O.<4>__Target4"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void D<T>.E<V>.Target4(T, V)"" IL_0026: newobj ""System.Action<T, V>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T, V> A<T>.B<V>.<>O.<4>__Target4"" IL_0030: ret } "); verifier.VerifyIL("A<T>.B<V>.Test4", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T, V> A<T>.B<V>.<>O.<4>__Target4"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void D<T>.E<V>.Target4(T, V)"" IL_000e: newobj ""System.Action<T, V>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T, V> A<T>.B<V>.<>O.<4>__Target4"" IL_0018: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<5>__Target5"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void E.Target5<T>(T)"" IL_0026: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T> A<T>.B<V>.<>O.<5>__Target5"" IL_0030: ret } "); verifier.VerifyIL("A<T>.B<V>.Test5", @" { // Code size 49 (0x31) .maxstack 2 IL_0000: ldsfld ""System.Action<T> A<T>.B<V>.<>O.<5>__Target5"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E.Target5<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> A<T>.B<V>.<>O.<5>__Target5"" IL_0018: ldsfld ""System.Action<V> A<T>.B<V>.<>O.<6>__Target5"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void E.Target5<V>(V)"" IL_0026: newobj ""System.Action<V>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<V> A<T>.B<V>.<>O.<6>__Target5"" IL_0030: ret } "); } [Fact] public void ContainersCanBeShared_MethodScoped0() { var source = @" using System; class C { void Test<T>() { Action a = Target0<T>; Action<T> b = Target1; Action c = D<T>.Target2; Action<C> d = E.Target3<T>; } static void Target0<T>() { } static void Target1<T>(T t) { } class D<K> { public static void Target2() { } } } static class E { public static void Target3<V>(this C c) { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Test>O__0_0", arity: 1 , "System.Action <0>__Target0" , "System.Action<T> <1>__Target1" , "System.Action <2>__Target2" , "System.Action<C> <3>__Target3" )); verifier.VerifyIL("C.Test<T>", @" { // Code size 97 (0x61) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Test>O__0_0<T>.<0>__Target0"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target0<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Test>O__0_0<T>.<0>__Target0"" IL_0018: ldsfld ""System.Action<T> C.<Test>O__0_0<T>.<1>__Target1"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void C.Target1<T>(T)"" IL_0026: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T> C.<Test>O__0_0<T>.<1>__Target1"" IL_0030: ldsfld ""System.Action C.<Test>O__0_0<T>.<2>__Target2"" IL_0035: brtrue.s IL_0048 IL_0037: ldnull IL_0038: ldftn ""void C.D<T>.Target2()"" IL_003e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0043: stsfld ""System.Action C.<Test>O__0_0<T>.<2>__Target2"" IL_0048: ldsfld ""System.Action<C> C.<Test>O__0_0<T>.<3>__Target3"" IL_004d: brtrue.s IL_0060 IL_004f: ldnull IL_0050: ldftn ""void E.Target3<T>(C)"" IL_0056: newobj ""System.Action<C>..ctor(object, System.IntPtr)"" IL_005b: stsfld ""System.Action<C> C.<Test>O__0_0<T>.<3>__Target3"" IL_0060: ret } "); } [Fact] public void ContainersCanBeShared_MethodScoped1() { var source = @" using System; class C { public static void Target0<T>() { } public static void Target1<T>(T t) { } public class D<T> { public static void Target2() { } } } static class E { static void Test<T>() { Action a = C.Target0<T>; Action<T> b = C.Target1; Action c = C.D<T>.Target2; Action<C> d = Target3<T>; } public static void Target3<T>(this C c) { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("E.<Test>O__0_0", arity: 1 , "System.Action <0>__Target0" , "System.Action<T> <1>__Target1" , "System.Action <2>__Target2" , "System.Action<C> <3>__Target3" )); verifier.VerifyIL("E.Test<T>", @" { // Code size 97 (0x61) .maxstack 2 IL_0000: ldsfld ""System.Action E.<Test>O__0_0<T>.<0>__Target0"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target0<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action E.<Test>O__0_0<T>.<0>__Target0"" IL_0018: ldsfld ""System.Action<T> E.<Test>O__0_0<T>.<1>__Target1"" IL_001d: brtrue.s IL_0030 IL_001f: ldnull IL_0020: ldftn ""void C.Target1<T>(T)"" IL_0026: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_002b: stsfld ""System.Action<T> E.<Test>O__0_0<T>.<1>__Target1"" IL_0030: ldsfld ""System.Action E.<Test>O__0_0<T>.<2>__Target2"" IL_0035: brtrue.s IL_0048 IL_0037: ldnull IL_0038: ldftn ""void C.D<T>.Target2()"" IL_003e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0043: stsfld ""System.Action E.<Test>O__0_0<T>.<2>__Target2"" IL_0048: ldsfld ""System.Action<C> E.<Test>O__0_0<T>.<3>__Target3"" IL_004d: brtrue.s IL_0060 IL_004f: ldnull IL_0050: ldftn ""void E.Target3<T>(C)"" IL_0056: newobj ""System.Action<C>..ctor(object, System.IntPtr)"" IL_005b: stsfld ""System.Action<C> E.<Test>O__0_0<T>.<3>__Target3"" IL_0060: ret } "); } [Fact] public void ContainersCanBeShared_SkippingUnused() { var source = @" using System; class C { public static void Target<T>(T t) { } } static class E { static void Test<T>() { void LF2<G>() { void LF3() { Action<T> d = C.Target<T>; static void LF4 () { Action<T> d = C.Target<T>; } LF4(); } void LF5() { Action<T> d = C.Target<T>; } LF3(); LF5(); } LF2<int>(); } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("E.<Test>O__0_0", arity: 1 , "System.Action<T> <0>__Target" )); verifier.VerifyIL("E.<Test>g__LF3|0_1<T, G>", @" { // Code size 30 (0x1e) .maxstack 2 IL_0000: ldsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0018: call ""void E.<Test>g__LF4|0_3<T, G>()"" IL_001d: ret } "); verifier.VerifyIL("E.<Test>g__LF4|0_3<T, G>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("E.<Test>g__LF5|0_2<T, G>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>(T)"" IL_000e: newobj ""System.Action<T>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<T> E.<Test>O__0_0<T>.<0>__Target"" IL_0018: ret } "); } [Fact] public void ContainersCanBeShared_LocalFunctions() { var source = @" using System; static class E { static void Test<T>() { void Owner<G>() { void LF1() { Action d = LF2; static void LF2() { Console.Write(""PA""); } d(); } void LF3() { Action d = LF2; static void LF2() { Console.Write(""SS""); } d(); } LF1(); LF3(); } Owner<int>(); } static void Main(string[] args) { Test<int>(); } } "; var verifier = CompileAndVerify(source, expectedOutput: PASS, symbolValidator: VerifyCacheContainer("E.<Owner>O__0_0", arity: 2 , "System.Action <0>__LF2" , "System.Action <1>__LF2" )); verifier.VerifyIL("E.<Test>g__LF1|0_1<T, G>", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action E.<Owner>O__0_0<T, G>.<0>__LF2"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.<Test>g__LF2|0_3<T, G>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action E.<Owner>O__0_0<T, G>.<0>__LF2"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); verifier.VerifyIL("E.<Test>g__LF3|0_2<T, G>", @" { // Code size 33 (0x21) .maxstack 2 IL_0000: ldsfld ""System.Action E.<Owner>O__0_0<T, G>.<1>__LF2"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void E.<Test>g__LF2|0_4<T, G>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action E.<Owner>O__0_0<T, G>.<1>__LF2"" IL_001b: callvirt ""void System.Action.Invoke()"" IL_0020: ret } "); } [Fact] public void NameAmbiguity_Containers0() { var source = @" void Owner<T>(int i) { var f = Target<T>; } void X() { void Owner<T>(string s) { var f = Target<T>; } } static void Target<T>() { } "; var verifier = CompileAndVerify(source, symbolValidator: static module => { VerifyCacheContainer("Program.<Owner>O__0_0", arity: 1, "System.Action <0>__Target")(module); VerifyCacheContainer("Program.<Owner>O__0_1", arity: 1, "System.Action <0>__Target")(module); }); verifier.VerifyIL("Program.<<Main>$>g__Owner|0_0<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<Owner>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void Program.<<Main>$>g__Target|0_2<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action Program.<Owner>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("Program.<<Main>$>g__Owner|0_3<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<Owner>O__0_1<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void Program.<<Main>$>g__Target|0_2<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action Program.<Owner>O__0_1<T>.<0>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Containers1() { var source = @" class C { void Owner<T>(int i) { var f = Target<T>; } void Owner<T>(string s) { var f = Target<T>; } static void Target<T>() { } } "; var verifier = CompileAndVerify(source, symbolValidator: static module => { VerifyCacheContainer("C.<Owner>O__0_0", arity: 1, "System.Action <0>__Target")(module); VerifyCacheContainer("C.<Owner>O__1_0", arity: 1, "System.Action <0>__Target")(module); }); verifier.VerifyIL("C.Owner<T>(int)", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C.Owner<T>(string)", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__1_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__1_0<T>.<0>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Containers2() { var source = @" class C { void Owner<T>(int i) { var f = Target<T>; } void F() { void Owner<T>(string s) { var f = Target<T>; } } static void Target<T>() { } } "; var verifier = CompileAndVerify(source, symbolValidator: static module => { VerifyCacheContainer("C.<Owner>O__0_0", arity: 1, "System.Action <0>__Target")(module); VerifyCacheContainer("C.<Owner>O__1_0", arity: 1, "System.Action <0>__Target")(module); }); verifier.VerifyIL("C.Owner<T>(int)", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C.<F>g__Owner|1_0<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__1_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.Target<T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__1_0<T>.<0>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Fields0() { var source = @" void F0() { var f = Target; static void Target() { } } void F1() { var f = Target; static void Target() { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("Program.<>O", arity: 0 , "System.Action <0>__Target" , "System.Action <1>__Target" )); verifier.VerifyIL("Program.<<Main>$>g__F0|0_0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void Program.<<Main>$>g__Target|0_2()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action Program.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("Program.<<Main>$>g__F1|0_1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<>O.<1>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void Program.<<Main>$>g__Target|0_3()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action Program.<>O.<1>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Fields2() { var source = @" class C { void F() { void Owner<T>() { void F0() { var f = Target<T>; static void Target<G>() { } } void F1() { var f = Target<T>; static void Target<G>() { } } } } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Owner>O__0_0", arity: 1 , "System.Action <0>__Target" , "System.Action <1>__Target" )); verifier.VerifyIL("C.<F>g__F0|0_1<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.<F>g__Target|0_3<T, T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C.<F>g__F1|0_2<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<Owner>O__0_0<T>.<1>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.<F>g__Target|0_4<T, T>()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<Owner>O__0_0<T>.<1>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Fields3() { var source = @" using System; class C { void F() { void Owner<T>() { Action<int> f = E<T>.Target; void F1() { Action<string> f = E<T>.Target; } } } } class E<T> { public static void Target(int i) { } public static void Target(string i) { } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<Owner>O__0_0", arity: 1 , "System.Action<System.Int32> <0>__Target" , "System.Action<System.String> <1>__Target" )); verifier.VerifyIL("C.<F>g__Owner|0_0<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<int> C.<Owner>O__0_0<T>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E<T>.Target(int)"" IL_000e: newobj ""System.Action<int>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<int> C.<Owner>O__0_0<T>.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C.<F>g__F1|0_1<T>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action<string> C.<Owner>O__0_0<T>.<1>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void E<T>.Target(string)"" IL_000e: newobj ""System.Action<string>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action<string> C.<Owner>O__0_0<T>.<1>__Target"" IL_0018: ret } "); } [Fact] public void NameAmbiguity_Fields1() { var source = @" class C { void F0() { var f = Target; static void Target() { } } void F1() { var f = Target; static void Target() { } } } "; var verifier = CompileAndVerify(source, symbolValidator: VerifyCacheContainer("C.<>O", arity: 0 , "System.Action <0>__Target" , "System.Action <1>__Target" )); verifier.VerifyIL("C.F0", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.<F0>g__Target|0_0()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<>O.<0>__Target"" IL_0018: ret } "); verifier.VerifyIL("C.F1", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Action C.<>O.<1>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""void C.<F1>g__Target|1_0()"" IL_000e: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Action C.<>O.<1>__Target"" IL_0018: ret } "); } [Fact] public void EventHandlers_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; using System.Reflection; class C { void Test() { AppDomain.CurrentDomain.AssemblyResolve += Target; } static Assembly Target(object sender, ResolveEventArgs e) => null; } "; CompileAndVerify(source).VerifyIL("C.Test", @" { // Code size 38 (0x26) .maxstack 3 IL_0000: call ""System.AppDomain System.AppDomain.CurrentDomain.get"" IL_0005: ldsfld ""System.ResolveEventHandler C.<>O.<0>__Target"" IL_000a: dup IL_000b: brtrue.s IL_0020 IL_000d: pop IL_000e: ldnull IL_000f: ldftn ""System.Reflection.Assembly C.Target(object, System.ResolveEventArgs)"" IL_0015: newobj ""System.ResolveEventHandler..ctor(object, System.IntPtr)"" IL_001a: dup IL_001b: stsfld ""System.ResolveEventHandler C.<>O.<0>__Target"" IL_0020: callvirt ""void System.AppDomain.AssemblyResolve.add"" IL_0025: ret } "); } [Fact] public void EventHandlers_TypeScoped_CouldBeModuleScoped1() { var source = @" using System; class MyEventArgs : EventArgs { } class C<TEventArgs> where TEventArgs : EventArgs { event EventHandler<TEventArgs> SomethingHappened; void Test() { var c = new C<MyEventArgs>(); c.SomethingHappened += D.Target; } } class D { public static void Target(object sender, MyEventArgs e) { } } "; CompileAndVerify(source).VerifyIL("C<TEventArgs>.Test", @" { // Code size 38 (0x26) .maxstack 3 IL_0000: newobj ""C<MyEventArgs>..ctor()"" IL_0005: ldsfld ""System.EventHandler<MyEventArgs> C<TEventArgs>.<>O.<0>__Target"" IL_000a: dup IL_000b: brtrue.s IL_0020 IL_000d: pop IL_000e: ldnull IL_000f: ldftn ""void D.Target(object, MyEventArgs)"" IL_0015: newobj ""System.EventHandler<MyEventArgs>..ctor(object, System.IntPtr)"" IL_001a: dup IL_001b: stsfld ""System.EventHandler<MyEventArgs> C<TEventArgs>.<>O.<0>__Target"" IL_0020: callvirt ""void C<MyEventArgs>.SomethingHappened.add"" IL_0025: ret } "); } [Fact] public void EventHandlers_TypeScoped0() { var source = @" using System; class C<TEventArgs> where TEventArgs : EventArgs { event EventHandler<TEventArgs> SomethingHappened; void Test() { this.SomethingHappened += Target; } static void Target(object sender, TEventArgs e) { } } "; CompileAndVerify(source).VerifyIL("C<TEventArgs>.Test", @" { // Code size 34 (0x22) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""System.EventHandler<TEventArgs> C<TEventArgs>.<>O.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""void C<TEventArgs>.Target(object, TEventArgs)"" IL_0011: newobj ""System.EventHandler<TEventArgs>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""System.EventHandler<TEventArgs> C<TEventArgs>.<>O.<0>__Target"" IL_001c: call ""void C<TEventArgs>.SomethingHappened.add"" IL_0021: ret } "); } [Fact] public void EventHandlers_MethodScoped0() { var source = @" using System; class C { void Test<TEventArgs>() where TEventArgs : EventArgs { var d = new D<TEventArgs>(); d.SomethingHappened += Target; } static void Target<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs { } } class D<TEventArgs> where TEventArgs : EventArgs { public event EventHandler<TEventArgs> SomethingHappened; } "; CompileAndVerify(source).VerifyIL("C.Test<TEventArgs>", @" { // Code size 38 (0x26) .maxstack 3 IL_0000: newobj ""D<TEventArgs>..ctor()"" IL_0005: ldsfld ""System.EventHandler<TEventArgs> C.<Test>O__0_0<TEventArgs>.<0>__Target"" IL_000a: dup IL_000b: brtrue.s IL_0020 IL_000d: pop IL_000e: ldnull IL_000f: ldftn ""void C.Target<TEventArgs>(object, TEventArgs)"" IL_0015: newobj ""System.EventHandler<TEventArgs>..ctor(object, System.IntPtr)"" IL_001a: dup IL_001b: stsfld ""System.EventHandler<TEventArgs> C.<Test>O__0_0<TEventArgs>.<0>__Target"" IL_0020: callvirt ""void D<TEventArgs>.SomethingHappened.add"" IL_0025: ret } "); } [Fact] public void AnonymousTypes_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { static void Main(string[] args) => Invoke(new { x = 0 }, Target); static void Invoke<T>(T t, Action<T> f) => f(t); static void Target<T>(T t) => Console.WriteLine(t); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("C.Main", @" { // Code size 39 (0x27) .maxstack 3 IL_0000: ldc.i4.0 IL_0001: newobj ""<>f__AnonymousType0<int>..ctor(int)"" IL_0006: ldsfld ""System.Action<<anonymous type: int x>> C.<>O.<0>__Target"" IL_000b: dup IL_000c: brtrue.s IL_0021 IL_000e: pop IL_000f: ldnull IL_0010: ldftn ""void C.Target<<anonymous type: int x>>(<anonymous type: int x>)"" IL_0016: newobj ""System.Action<<anonymous type: int x>>..ctor(object, System.IntPtr)"" IL_001b: dup IL_001c: stsfld ""System.Action<<anonymous type: int x>> C.<>O.<0>__Target"" IL_0021: call ""void C.Invoke<<anonymous type: int x>>(<anonymous type: int x>, System.Action<<anonymous type: int x>>)"" IL_0026: ret } "); } [Fact] public void AnonymousTypes_TypeScoped0() { var source = @" using System; class C { static void Main(string[] args) => (new D<int>()).Test(0); } class D<G> { public void Test(G g) => Invoke(new { x = g }, Target); static void Invoke<T>(T t, Action<T> f) => f(t); static void Target<T>(T t) => Console.WriteLine(t); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("D<G>.Test", @" { // Code size 39 (0x27) .maxstack 3 IL_0000: ldarg.1 IL_0001: newobj ""<>f__AnonymousType0<G>..ctor(G)"" IL_0006: ldsfld ""System.Action<<anonymous type: G x>> D<G>.<>O.<0>__Target"" IL_000b: dup IL_000c: brtrue.s IL_0021 IL_000e: pop IL_000f: ldnull IL_0010: ldftn ""void D<G>.Target<<anonymous type: G x>>(<anonymous type: G x>)"" IL_0016: newobj ""System.Action<<anonymous type: G x>>..ctor(object, System.IntPtr)"" IL_001b: dup IL_001c: stsfld ""System.Action<<anonymous type: G x>> D<G>.<>O.<0>__Target"" IL_0021: call ""void D<G>.Invoke<<anonymous type: G x>>(<anonymous type: G x>, System.Action<<anonymous type: G x>>)"" IL_0026: ret } "); } [Fact] public void AnonymousTypes_TypeScoped1() { var source = @" using System; class C { static void Main(string[] args) => (new D<int>()).Test(0); } class D<G> { public void Test(G g) => Invoke(new { x = g }, E.Target); static void Invoke<T>(T t, Action<T> f) => f(t); } class E { public static void Target<T>(T t) => Console.WriteLine(t); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("D<G>.Test", @" { // Code size 39 (0x27) .maxstack 3 IL_0000: ldarg.1 IL_0001: newobj ""<>f__AnonymousType0<G>..ctor(G)"" IL_0006: ldsfld ""System.Action<<anonymous type: G x>> D<G>.<>O.<0>__Target"" IL_000b: dup IL_000c: brtrue.s IL_0021 IL_000e: pop IL_000f: ldnull IL_0010: ldftn ""void E.Target<<anonymous type: G x>>(<anonymous type: G x>)"" IL_0016: newobj ""System.Action<<anonymous type: G x>>..ctor(object, System.IntPtr)"" IL_001b: dup IL_001c: stsfld ""System.Action<<anonymous type: G x>> D<G>.<>O.<0>__Target"" IL_0021: call ""void D<G>.Invoke<<anonymous type: G x>>(<anonymous type: G x>, System.Action<<anonymous type: G x>>)"" IL_0026: ret } "); } [Fact] public void AnonymousTypes_TypeScoped2() { var source = @" using System; class C { static void Main(string[] args) => D<int>.Test(); } class D<G> { delegate void MyAction<T>(T t); public static void Test() => Invoke(new { x = 0 }, Target); static void Invoke<T>(T t, MyAction<T> f) => f(t); static void Target<T>(T t) => Console.WriteLine(t); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("D<G>.Test", @" { // Code size 39 (0x27) .maxstack 3 IL_0000: ldc.i4.0 IL_0001: newobj ""<>f__AnonymousType0<int>..ctor(int)"" IL_0006: ldsfld ""D<G>.MyAction<<anonymous type: int x>> D<G>.<>O.<0>__Target"" IL_000b: dup IL_000c: brtrue.s IL_0021 IL_000e: pop IL_000f: ldnull IL_0010: ldftn ""void D<G>.Target<<anonymous type: int x>>(<anonymous type: int x>)"" IL_0016: newobj ""D<G>.MyAction<<anonymous type: int x>>..ctor(object, System.IntPtr)"" IL_001b: dup IL_001c: stsfld ""D<G>.MyAction<<anonymous type: int x>> D<G>.<>O.<0>__Target"" IL_0021: call ""void D<G>.Invoke<<anonymous type: int x>>(<anonymous type: int x>, D<G>.MyAction<<anonymous type: int x>>)"" IL_0026: ret } "); } [Fact] public void AnonymousTypes_MethodScoped0() { var source = @" using System; class C { static void Main(string[] args) => D.Test(0); } class D { public static void Test<T>(T t) => Invoke(new { x = t }, Target); static void Invoke<T>(T t, Action<T> f) => f(t); static void Target<T>(T t) => Console.WriteLine(t); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("D.Test<T>", @" { // Code size 39 (0x27) .maxstack 3 IL_0000: ldarg.0 IL_0001: newobj ""<>f__AnonymousType0<T>..ctor(T)"" IL_0006: ldsfld ""System.Action<<anonymous type: T x>> D.<Test>O__0_0<T>.<0>__Target"" IL_000b: dup IL_000c: brtrue.s IL_0021 IL_000e: pop IL_000f: ldnull IL_0010: ldftn ""void D.Target<<anonymous type: T x>>(<anonymous type: T x>)"" IL_0016: newobj ""System.Action<<anonymous type: T x>>..ctor(object, System.IntPtr)"" IL_001b: dup IL_001c: stsfld ""System.Action<<anonymous type: T x>> D.<Test>O__0_0<T>.<0>__Target"" IL_0021: call ""void D.Invoke<<anonymous type: T x>>(<anonymous type: T x>, System.Action<<anonymous type: T x>>)"" IL_0026: ret } "); } [Fact] public void AnonymousTypes_MethodScoped1() { var source = @" using System; class C { static void Main(string[] args) => D.Test(0); } class D { public static void Test<T>(T t) => Invoke(t, new { x = 0 }, Target); static void Invoke<T, V>(T t, V v, Action<T, V> f) => f(t, v); static void Target<T, V>(T t, V v) => Console.WriteLine(v); } "; CompileAndVerify(source, expectedOutput: "{ x = 0 }").VerifyIL("D.Test<T>", @" { // Code size 40 (0x28) .maxstack 4 IL_0000: ldarg.0 IL_0001: ldc.i4.0 IL_0002: newobj ""<>f__AnonymousType0<int>..ctor(int)"" IL_0007: ldsfld ""System.Action<T, <anonymous type: int x>> D.<Test>O__0_0<T>.<0>__Target"" IL_000c: dup IL_000d: brtrue.s IL_0022 IL_000f: pop IL_0010: ldnull IL_0011: ldftn ""void D.Target<T, <anonymous type: int x>>(T, <anonymous type: int x>)"" IL_0017: newobj ""System.Action<T, <anonymous type: int x>>..ctor(object, System.IntPtr)"" IL_001c: dup IL_001d: stsfld ""System.Action<T, <anonymous type: int x>> D.<Test>O__0_0<T>.<0>__Target"" IL_0022: call ""void D.Invoke<T, <anonymous type: int x>>(T, <anonymous type: int x>, System.Action<T, <anonymous type: int x>>)"" IL_0027: ret } "); } [Fact] public void AnonymousClass_AnonymousDelegate0() { var source = @" using System; class D { public void Owner<T>() { static void Test<NotUsed>(T t) { var f = F<T>; var a = new { x = f }; Invoke(a, Target); } } static void F<T>(ref T t) { } static void Invoke<T>(T t, Action<T> f) { } static void Target<T>(T t) { } } "; CompileAndVerify(source).VerifyIL("D.<Owner>g__Test|0_0<T, NotUsed>", @" { // Code size 65 (0x41) .maxstack 3 IL_0000: ldsfld ""<anonymous delegate> D.<Owner>O__0_0<T>.<0>__F"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D.F<T>(ref T)"" IL_0010: newobj ""<>A{00000001}<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""<anonymous delegate> D.<Owner>O__0_0<T>.<0>__F"" IL_001b: newobj ""<>f__AnonymousType0<<anonymous delegate>>..ctor(<anonymous delegate>)"" IL_0020: ldsfld ""System.Action<<anonymous type: <anonymous delegate> x>> D.<Owner>O__0_0<T>.<1>__Target"" IL_0025: dup IL_0026: brtrue.s IL_003b IL_0028: pop IL_0029: ldnull IL_002a: ldftn ""void D.Target<<anonymous type: <anonymous delegate> x>>(<anonymous type: <anonymous delegate> x>)"" IL_0030: newobj ""System.Action<<anonymous type: <anonymous delegate> x>>..ctor(object, System.IntPtr)"" IL_0035: dup IL_0036: stsfld ""System.Action<<anonymous type: <anonymous delegate> x>> D.<Owner>O__0_0<T>.<1>__Target"" IL_003b: call ""void D.Invoke<<anonymous type: <anonymous delegate> x>>(<anonymous type: <anonymous delegate> x>, System.Action<<anonymous type: <anonymous delegate> x>>)"" IL_0040: ret } "); } [Fact] public void AnonymousClass_AnonymousDelegate1() { var source = @" using System; class D<T> { public void Top<N0>() { static void Test<N1>(T t) { var f = F; var a = new { x = f }; Invoke(a, Target); } } static void F(ref T t) { } static void Invoke<G>(G t, Action<G> f) { } static void Target<G>(G t) { } } "; CompileAndVerify(source).VerifyIL("D<T>.<Top>g__Test|0_0<N0, N1>", @" { // Code size 65 (0x41) .maxstack 3 IL_0000: ldsfld ""<anonymous delegate> D<T>.<>O.<0>__F"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void D<T>.F(ref T)"" IL_0010: newobj ""<>A{00000001}<T>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""<anonymous delegate> D<T>.<>O.<0>__F"" IL_001b: newobj ""<>f__AnonymousType0<<anonymous delegate>>..ctor(<anonymous delegate>)"" IL_0020: ldsfld ""System.Action<<anonymous type: <anonymous delegate> x>> D<T>.<>O.<1>__Target"" IL_0025: dup IL_0026: brtrue.s IL_003b IL_0028: pop IL_0029: ldnull IL_002a: ldftn ""void D<T>.Target<<anonymous type: <anonymous delegate> x>>(<anonymous type: <anonymous delegate> x>)"" IL_0030: newobj ""System.Action<<anonymous type: <anonymous delegate> x>>..ctor(object, System.IntPtr)"" IL_0035: dup IL_0036: stsfld ""System.Action<<anonymous type: <anonymous delegate> x>> D<T>.<>O.<1>__Target"" IL_003b: call ""void D<T>.Invoke<<anonymous type: <anonymous delegate> x>>(<anonymous type: <anonymous delegate> x>, System.Action<<anonymous type: <anonymous delegate> x>>)"" IL_0040: ret } "); } [Fact] public void Pointer_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { unsafe void Test() { Func<int*[]> t = Target; t(); } unsafe static int*[] Target() => default(int*[]); } "; CompileAndVerify(source, options: TestOptions.UnsafeReleaseDll).VerifyIL("C.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<int*[]> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int*[] C.Target()"" IL_0010: newobj ""System.Func<int*[]>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int*[]> C.<>O.<0>__Target"" IL_001b: callvirt ""int*[] System.Func<int*[]>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Pointer_TypeScoped0() { var source = @" using System; class C<T> { unsafe void Test() { Func<T, int*[]> t = Target; t(default(T)); } unsafe static int*[] Target(T t) => default(int*[]); } "; CompileAndVerify(source, options: TestOptions.UnsafeReleaseDll).VerifyIL("C<T>.Test", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Func<T, int*[]> C<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int*[] C<T>.Target(T)"" IL_0010: newobj ""System.Func<T, int*[]>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, int*[]> C<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""int*[] System.Func<T, int*[]>.Invoke(T)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void Pointer_MethodScoped0() { var source = @" using System; class C { unsafe void Test<T>(T t) { Func<T, int*[]> f = Target<T>; f(t); } unsafe static int*[] Target<G>(G g) => default(int*[]); } "; CompileAndVerify(source, options: TestOptions.UnsafeReleaseDll).VerifyIL("C.Test<T>", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<T, int*[]> C.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int*[] C.Target<T>(T)"" IL_0010: newobj ""System.Func<T, int*[]>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, int*[]> C.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldarg.1 IL_001c: callvirt ""int*[] System.Func<T, int*[]>.Invoke(T)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void Dynamic_TypeScoped_CouldBeModuleScoped0() { var source = @" using System; class C { void Test() { Func<dynamic> t = Target; t(); } static dynamic Target() => 0; } "; CompileAndVerify(source).VerifyIL("C.Test", @" { // Code size 34 (0x22) .maxstack 2 IL_0000: ldsfld ""System.Func<dynamic> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.Target()"" IL_0010: newobj ""System.Func<dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<dynamic> C.<>O.<0>__Target"" IL_001b: callvirt ""dynamic System.Func<dynamic>.Invoke()"" IL_0020: pop IL_0021: ret } "); } [Fact] public void Dynamic_TypeScoped0() { var source = @" using System; class C<T> { void Test() { Func<T, dynamic> t = Target; t(default(T)); } static dynamic Target(T t) => 0; } "; CompileAndVerify(source).VerifyIL("C<T>.Test", @" { // Code size 43 (0x2b) .maxstack 2 .locals init (T V_0) IL_0000: ldsfld ""System.Func<T, dynamic> C<T>.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C<T>.Target(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C<T>.<>O.<0>__Target"" IL_001b: ldloca.s V_0 IL_001d: initobj ""T"" IL_0023: ldloc.0 IL_0024: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0029: pop IL_002a: ret } "); } [Fact] public void Dynamic_MethodScoped0() { var source = @" using System; class C { void Test<T>(T t) { Func<T, dynamic> f = Target<T>; f(t); } static dynamic Target<G>(G g) => 0; } "; CompileAndVerify(source).VerifyIL("C.Test<T>", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> C.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.Target<T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldarg.1 IL_001c: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void SynthesizedAnonymousDelegate_TypeScoped0() { var source = @" using System; class C { void Test<T>(T t) { G(Target<int>); } void G(Delegate d) {} static dynamic Target<G>(ref G g) => 0; } "; CompileAndVerify(source).VerifyIL("C.Test<T>", @" { // Code size 34 (0x22) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""dynamic C.Target<int>(ref int)"" IL_0011: newobj ""<>F{00000001}<int, dynamic>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""<anonymous delegate> C.<>O.<0>__Target"" IL_001c: call ""void C.G(System.Delegate)"" IL_0021: ret } "); } [Fact] public void SynthesizedAnonymousDelegate_MethodScoped0() { var source = @" using System; class C { void Test<T>(T t) { G(Target<T>); } void G(Delegate d) {} static dynamic Target<G>(ref G g) => 0; } "; CompileAndVerify(source).VerifyIL("C.Test<T>", @" { // Code size 34 (0x22) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""dynamic C.Target<T>(ref T)"" IL_0011: newobj ""<>F{00000001}<T, dynamic>..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""<anonymous delegate> C.<Test>O__0_0<T>.<0>__Target"" IL_001c: call ""void C.G(System.Delegate)"" IL_0021: ret } "); } [Fact] public void TopLevelMethod_LocalFunctions_TypeScoped0() { var source = @" using System; class C { void Test(int t) { Func<int, dynamic> f = Target<int>; f(t); static dynamic Target<G>(G g) => 0; } } "; CompileAndVerify(source).VerifyIL("C.Test", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<int, dynamic> C.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.<Test>g__Target|0_0<int>(int)"" IL_0010: newobj ""System.Func<int, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int, dynamic> C.<>O.<0>__Target"" IL_001b: ldarg.1 IL_001c: callvirt ""dynamic System.Func<int, dynamic>.Invoke(int)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void TopLevelMethod_LocalFunctions_NotStatic() { var source = @" using System; class C { void Test(int t) { Func<int, dynamic> f = Target<int>; f(t); dynamic Target<G>(G g) => 0; } } "; CompileAndVerify(source).VerifyIL("C.Test", @" { // Code size 20 (0x14) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""dynamic C.<Test>g__Target|0_0<int>(int)"" IL_0007: newobj ""System.Func<int, dynamic>..ctor(object, System.IntPtr)"" IL_000c: ldarg.1 IL_000d: callvirt ""dynamic System.Func<int, dynamic>.Invoke(int)"" IL_0012: pop IL_0013: ret } "); } [Fact] public void TopLevelMethod_LocalFunctions_MethodScoped0() { var source = @" using System; class C { void Test<T>(T t) { Func<T, dynamic> f = Target<T>; f(t); static dynamic Target<G>(G g) => 0; } } "; CompileAndVerify(source).VerifyIL("C.Test<T>", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> C.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.<Test>g__Target|0_0<T, T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldarg.1 IL_001c: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void Local_LocalFunctions_MethodScoped0() { var source = @" using System; class C { void TopLevel<T>(T t) { void Test() { Func<T, dynamic> f = Target<T>; f(t); static dynamic Target<G>(G g) => 0; } } } "; CompileAndVerify(source).VerifyIL("C.<TopLevel>g__Test|0_0<T>", @" { // Code size 40 (0x28) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.<TopLevel>g__Target|0_1<T, T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_001b: ldarg.0 IL_001c: ldfld ""T C.<>c__DisplayClass0_0<T>.t"" IL_0021: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0026: pop IL_0027: ret } "); } [Fact] public void Lambda_Local_LocalFunctions_MethodScoped0() { var source = @" using System; class C { void TopLevel<T>(T t) { Action x = () => { void Test() { Func<T, dynamic> f = Target<T>; f(t); static dynamic Target<G>(G g) => 0; } Test(); }; x(); } } "; CompileAndVerify(source).VerifyIL("C.<>c__DisplayClass0_0<T>.<TopLevel>g__Test|1", @" { // Code size 40 (0x28) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.<TopLevel>g__Target|0_2<T, T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_001b: ldarg.0 IL_001c: ldfld ""T C.<>c__DisplayClass0_0<T>.t"" IL_0021: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0026: pop IL_0027: ret } "); } [Fact] public void Lambda_Local_LocalFunctions_MethodScoped1() { var source = @" using System; class C { void TopLevel<T>(T t) { Action y = () => { void Test() { /* Test method ordinals in generated names */ } Test(); }; Action x = () => { void Test() { Func<T, dynamic> f = Target<T>; f(t); static dynamic Target<G>(G g) => 0; } Test(); }; x(); y(); } } "; CompileAndVerify(source).VerifyIL("C.<>c__DisplayClass0_0<T>.<TopLevel>g__Test|3", @" { // Code size 40 (0x28) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic C.<TopLevel>g__Target|0_4<T, T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> C.<TopLevel>O__0_0<T>.<0>__Target"" IL_001b: ldarg.0 IL_001c: ldfld ""T C.<>c__DisplayClass0_0<T>.t"" IL_0021: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0026: pop IL_0027: ret } "); } [Fact] public void TopLevelStatement_Lambda_Local_LocalFunctions_MethodScoped0() { var source = @" using System; Action y = () => { void Test() { /* Test method ordinals in generated names */ } Test(); }; Action x = () => { void Test<T>(T t) { Func<T, dynamic> f = Target<T>; f(t); static dynamic Target<G>(G g) => 0; } Test(0); }; x(); y(); "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_3<T>", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<T, dynamic> Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic Program.<<Main>$>g__Target|0_4<T, T>(T)"" IL_0010: newobj ""System.Func<T, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, dynamic> Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldarg.0 IL_001c: callvirt ""dynamic System.Func<T, dynamic>.Invoke(T)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void TopLevelStatement_Lambda_Local_LocalFunctions_MethodScoped1() { var source = @" var y = () => { void Test() { /* Test method ordinals in generated names */ } Test(); }; var x = () => { void Test<T>(T t) { var f = Target<int>; f(0); static dynamic Target<G>(G g) { T f = default; return f; } } Test(false); }; x(); y(); "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_3<T>", @" { // Code size 35 (0x23) .maxstack 2 IL_0000: ldsfld ""System.Func<int, dynamic> Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""dynamic Program.<<Main>$>g__Target|0_4<T, int>(int)"" IL_0010: newobj ""System.Func<int, dynamic>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int, dynamic> Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: ldc.i4.0 IL_001c: callvirt ""dynamic System.Func<int, dynamic>.Invoke(int)"" IL_0021: pop IL_0022: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_TypeScoped0() { var source = @" (System.Action a, int _) = (Target, 0); static void Target() { } "; CompileAndVerify(source).VerifyIL("<top-level-statements-entry-point>", @" { // Code size 29 (0x1d) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<>O.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void Program.<<Main>$>g__Target|0_0()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action Program.<>O.<0>__Target"" IL_001b: pop IL_001c: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_TypeScoped1() { var source = @" var t = Target; static (int a, int b) Target() => (0, 0); "; CompileAndVerify(source).VerifyIL("<top-level-statements-entry-point>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<System.ValueTuple<int, int>> Program.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<int, int> Program.<<Main>$>g__Target|0_0()"" IL_000e: newobj ""System.Func<System.ValueTuple<int, int>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<System.ValueTuple<int, int>> Program.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_MethodScoped0() { var source = @" Test(0); static void Test<T>(T t) { (System.Action a, int _) = (Target, 0); static void Target() { } } "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_0<T>", @" { // Code size 29 (0x1d) .maxstack 2 IL_0000: ldsfld ""System.Action Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void Program.<<Main>$>g__Target|0_1<T>()"" IL_0010: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Action Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: pop IL_001c: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_MethodScoped1() { var source = @" Test(0); static void Test<T>(T t) { (System.Func<(T, int)> a, int _) = (Target, 0); static (T, int) Target() => (default(T), 0); } "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_0<T>", @" { // Code size 29 (0x1d) .maxstack 2 IL_0000: ldsfld ""System.Func<System.ValueTuple<T, int>> Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""System.ValueTuple<T, int> Program.<<Main>$>g__Target|0_1<T>()"" IL_0010: newobj ""System.Func<System.ValueTuple<T, int>>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<System.ValueTuple<T, int>> Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: pop IL_001c: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_MethodScoped2() { var source = @" Test(0); static void Test<T>(T t) { (System.Func<T, (T, T)> a, int _) = (Target<T>, 0); static (T, G) Target<G>(G g) => (default(T), g); } "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_0<T>", @" { // Code size 29 (0x1d) .maxstack 2 IL_0000: ldsfld ""System.Func<T, System.ValueTuple<T, T>> Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""System.ValueTuple<T, T> Program.<<Main>$>g__Target|0_1<T, T>(T)"" IL_0010: newobj ""System.Func<T, System.ValueTuple<T, T>>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, System.ValueTuple<T, T>> Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: pop IL_001c: ret } "); } [Fact] public void TopLevelStatement_Tuples_LocalFunction_MethodScoped3() { var source = @" Test(0); static void Test<T>(T t) { (System.Func<T, (T, T)> a, int _) = (Target<T, T>, 0); } static (T, G) Target<T, G>(G g) => (default(T), g); "; CompileAndVerify(source).VerifyIL("Program.<<Main>$>g__Test|0_0<T>", @" { // Code size 29 (0x1d) .maxstack 2 IL_0000: ldsfld ""System.Func<T, System.ValueTuple<T, T>> Program.<Test>O__0_0<T>.<0>__Target"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""System.ValueTuple<T, T> Program.<<Main>$>g__Target|0_1<T, T>(T)"" IL_0010: newobj ""System.Func<T, System.ValueTuple<T, T>>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<T, System.ValueTuple<T, T>> Program.<Test>O__0_0<T>.<0>__Target"" IL_001b: pop IL_001c: ret } "); } [Fact] public void Tuples_LocalFunction_TypeScoped0() { var source = @" class C<T> { void Test() { var x = Target; static (T, T) Target(T t) => (t, t); } } "; CompileAndVerify(source).VerifyIL("C<T>.Test", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T, System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<T, T> C<T>.<Test>g__Target|0_0(T)"" IL_000e: newobj ""System.Func<T, System.ValueTuple<T, T>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T, System.ValueTuple<T, T>> C<T>.<>O.<0>__Target"" IL_0018: ret } "); } [Fact] public void Tuples_LocalFunction_MethodScoped0() { var source = @" class C<T> { void Test<G>() { var x = Target; static (T, G) Target(T t, G g) => (t, g); } } "; CompileAndVerify(source).VerifyIL("C<T>.Test<G>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T, G, System.ValueTuple<T, G>> C<T>.<Test>O__0_0<G>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<T, G> C<T>.<Test>g__Target|0_0<G>(T, G)"" IL_000e: newobj ""System.Func<T, G, System.ValueTuple<T, G>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T, G, System.ValueTuple<T, G>> C<T>.<Test>O__0_0<G>.<0>__Target"" IL_0018: ret } "); } [Fact] public void Tuples_LocalFunction_MethodScoped1() { var source = @" class C<T> { void Test<G>() { var x = Target<T>; static (T, G, V) Target<V>(T t, G g, V v) => (t, g, v); } } "; CompileAndVerify(source).VerifyIL("C<T>.Test<G>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<T, G, T, System.ValueTuple<T, G, T>> C<T>.<Test>O__0_0<G>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<T, G, T> C<T>.<Test>g__Target|0_0<G, T>(T, G, T)"" IL_000e: newobj ""System.Func<T, G, T, System.ValueTuple<T, G, T>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<T, G, T, System.ValueTuple<T, G, T>> C<T>.<Test>O__0_0<G>.<0>__Target"" IL_0018: ret } "); } [Fact] public void Tuples_LocalFunction_MethodScoped2() { var source = @" class M<N> { void F<I>() { void Test<C>() { var x = Target<N>; static (N, I, C, E) Target<E>(N n, I i, C c, E e) => (n, i, c, e); } } } "; CompileAndVerify(source).VerifyIL("M<N>.<F>g__Test|0_0<I, C>", @" { // Code size 25 (0x19) .maxstack 2 IL_0000: ldsfld ""System.Func<N, I, C, N, System.ValueTuple<N, I, C, N>> M<N>.<Test>O__0_0<I, C>.<0>__Target"" IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn ""System.ValueTuple<N, I, C, N> M<N>.<F>g__Target|0_1<I, C, N>(N, I, C, N)"" IL_000e: newobj ""System.Func<N, I, C, N, System.ValueTuple<N, I, C, N>>..ctor(object, System.IntPtr)"" IL_0013: stsfld ""System.Func<N, I, C, N, System.ValueTuple<N, I, C, N>> M<N>.<Test>O__0_0<I, C>.<0>__Target"" IL_0018: ret } "); } [Fact] public void TestConditionalOperatorMethodGroup() { var source = @" class C { static void Main() { bool b = true; System.Func<int> f = null; System.Console.WriteLine(f); System.Func<int> g1 = b ? f : M; System.Console.WriteLine(g1); System.Func<int> g2 = b ? M : f; System.Console.WriteLine(g2); } static int M() { return 0; } }"; var comp = CompileAndVerify(source, parseOptions: TestOptions.Regular11); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @" { // Code size 85 (0x55) .maxstack 3 .locals init (System.Func<int> V_0) //f IL_0000: ldc.i4.1 IL_0001: ldnull IL_0002: stloc.0 IL_0003: ldloc.0 IL_0004: call ""void System.Console.WriteLine(object)"" IL_0009: dup IL_000a: brtrue.s IL_0029 IL_000c: ldsfld ""System.Func<int> C.<>O.<0>__M"" IL_0011: dup IL_0012: brtrue.s IL_002a IL_0014: pop IL_0015: ldnull IL_0016: ldftn ""int C.M()"" IL_001c: newobj ""System.Func<int>..ctor(object, System.IntPtr)"" IL_0021: dup IL_0022: stsfld ""System.Func<int> C.<>O.<0>__M"" IL_0027: br.s IL_002a IL_0029: ldloc.0 IL_002a: call ""void System.Console.WriteLine(object)"" IL_002f: brtrue.s IL_0034 IL_0031: ldloc.0 IL_0032: br.s IL_004f IL_0034: ldsfld ""System.Func<int> C.<>O.<0>__M"" IL_0039: dup IL_003a: brtrue.s IL_004f IL_003c: pop IL_003d: ldnull IL_003e: ldftn ""int C.M()"" IL_0044: newobj ""System.Func<int>..ctor(object, System.IntPtr)"" IL_0049: dup IL_004a: stsfld ""System.Func<int> C.<>O.<0>__M"" IL_004f: call ""void System.Console.WriteLine(object)"" IL_0054: ret } "); } [Fact] public void WinMdEventAssignment() { var source = @" class C { public event System.Action Instance; public static event System.Action Static; } class D { C c; void InstanceAdd() { c.Instance += Action; } void InstanceRemove() { c.Instance -= Action; } static void StaticAdd() { C.Static += Action; } static void StaticRemove() { C.Static -= Action; } static void Action() { } } "; var verifier = CompileAndVerifyWithWinRt(source, parseOptions: TestOptions.Regular11, options: TestOptions.ReleaseWinMD); verifier.VerifyIL("D.InstanceAdd", @" { // Code size 64 (0x40) .maxstack 4 .locals init (C V_0) IL_0000: ldarg.0 IL_0001: ldfld ""C D.c"" IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldftn ""System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken C.Instance.add"" IL_000e: newobj ""System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_0013: ldloc.0 IL_0014: ldftn ""void C.Instance.remove"" IL_001a: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_001f: ldsfld ""System.Action D.<>O.<0>__Action"" IL_0024: dup IL_0025: brtrue.s IL_003a IL_0027: pop IL_0028: ldnull IL_0029: ldftn ""void D.Action()"" IL_002f: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0034: dup IL_0035: stsfld ""System.Action D.<>O.<0>__Action"" IL_003a: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler<System.Action>(System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_003f: ret }"); verifier.VerifyIL("D.InstanceRemove", @" { // Code size 50 (0x32) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldfld ""C D.c"" IL_0006: ldftn ""void C.Instance.remove"" IL_000c: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_0011: ldsfld ""System.Action D.<>O.<0>__Action"" IL_0016: dup IL_0017: brtrue.s IL_002c IL_0019: pop IL_001a: ldnull IL_001b: ldftn ""void D.Action()"" IL_0021: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0026: dup IL_0027: stsfld ""System.Action D.<>O.<0>__Action"" IL_002c: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.RemoveEventHandler<System.Action>(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_0031: ret }"); verifier.VerifyIL("D.StaticAdd", @" { // Code size 57 (0x39) .maxstack 4 IL_0000: ldnull IL_0001: ldftn ""System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken C.Static.add"" IL_0007: newobj ""System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_000c: ldnull IL_000d: ldftn ""void C.Static.remove"" IL_0013: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_0018: ldsfld ""System.Action D.<>O.<0>__Action"" IL_001d: dup IL_001e: brtrue.s IL_0033 IL_0020: pop IL_0021: ldnull IL_0022: ldftn ""void D.Action()"" IL_0028: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_002d: dup IL_002e: stsfld ""System.Action D.<>O.<0>__Action"" IL_0033: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler<System.Action>(System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_0038: ret }"); verifier.VerifyIL("D.StaticRemove", @" { // Code size 45 (0x2d) .maxstack 3 IL_0000: ldnull IL_0001: ldftn ""void C.Static.remove"" IL_0007: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_000c: ldsfld ""System.Action D.<>O.<0>__Action"" IL_0011: dup IL_0012: brtrue.s IL_0027 IL_0014: pop IL_0015: ldnull IL_0016: ldftn ""void D.Action()"" IL_001c: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0021: dup IL_0022: stsfld ""System.Action D.<>O.<0>__Action"" IL_0027: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.RemoveEventHandler<System.Action>(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_002c: ret }"); } [Fact] public void WinMdEventFieldAssignment() { var source = @" class C { public event System.Action Instance; public static event System.Action Static; void InstanceAssign() { Instance = Action; } static void StaticAssign() { Static = Action; } static void Action() { } } "; var verifier = CompileAndVerifyWithWinRt(source, parseOptions: TestOptions.Regular11, options: TestOptions.ReleaseWinMD); verifier.VerifyIL("C.InstanceAssign", @" { // Code size 74 (0x4a) .maxstack 4 IL_0000: ldarg.0 IL_0001: ldftn ""void C.Instance.remove"" IL_0007: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_000c: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.RemoveAllEventHandlers(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>)"" IL_0011: ldarg.0 IL_0012: ldftn ""System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken C.Instance.add"" IL_0018: newobj ""System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_001d: ldarg.0 IL_001e: ldftn ""void C.Instance.remove"" IL_0024: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_0029: ldsfld ""System.Action C.<>O.<0>__Action"" IL_002e: dup IL_002f: brtrue.s IL_0044 IL_0031: pop IL_0032: ldnull IL_0033: ldftn ""void C.Action()"" IL_0039: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_003e: dup IL_003f: stsfld ""System.Action C.<>O.<0>__Action"" IL_0044: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler<System.Action>(System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_0049: ret }"); verifier.VerifyIL("C.StaticAssign", @" { // Code size 74 (0x4a) .maxstack 4 IL_0000: ldnull IL_0001: ldftn ""void C.Static.remove"" IL_0007: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_000c: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.RemoveAllEventHandlers(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>)"" IL_0011: ldnull IL_0012: ldftn ""System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken C.Static.add"" IL_0018: newobj ""System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_001d: ldnull IL_001e: ldftn ""void C.Static.remove"" IL_0024: newobj ""System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>..ctor(object, System.IntPtr)"" IL_0029: ldsfld ""System.Action C.<>O.<0>__Action"" IL_002e: dup IL_002f: brtrue.s IL_0044 IL_0031: pop IL_0032: ldnull IL_0033: ldftn ""void C.Action()"" IL_0039: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_003e: dup IL_003f: stsfld ""System.Action C.<>O.<0>__Action"" IL_0044: call ""void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.AddEventHandler<System.Action>(System.Func<System.Action, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken>, System.Action)"" IL_0049: ret }"); } [Fact] public void LockDelegate() { var text = @" delegate void D(string p1); partial class Test { public static void Main() { D d1; lock (d1 = PM) { d1(""PASS""); } } static partial void PM(string p2); static partial void PM(string p2) { System.Console.WriteLine(p2); } } "; CompileAndVerify(text, parseOptions: TestOptions.Regular11, expectedOutput: PASS).VerifyIL("Test.Main", @" { // Code size 64 (0x40) .maxstack 2 .locals init (D V_0, //d1 D V_1, bool V_2) IL_0000: ldsfld ""D Test.<>O.<0>__PM"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""void Test.PM(string)"" IL_0010: newobj ""D..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""D Test.<>O.<0>__PM"" IL_001b: dup IL_001c: stloc.0 IL_001d: stloc.1 IL_001e: ldc.i4.0 IL_001f: stloc.2 .try { IL_0020: ldloc.1 IL_0021: ldloca.s V_2 IL_0023: call ""void System.Threading.Monitor.Enter(object, ref bool)"" IL_0028: ldloc.0 IL_0029: ldstr ""PASS"" IL_002e: callvirt ""void D.Invoke(string)"" IL_0033: leave.s IL_003f } finally { IL_0035: ldloc.2 IL_0036: brfalse.s IL_003e IL_0038: ldloc.1 IL_0039: call ""void System.Threading.Monitor.Exit(object)"" IL_003e: endfinally } IL_003f: ret } "); } [Fact] public void NullCoalescingAssignmentValidRHS() { CompileAndVerify(@" using System; public class C { public static void Main() { Action a = null; (a ??= TestMethod)(); (a ??= () => {})(); } static void TestMethod() => Console.WriteLine(""In TestMethod""); } ", parseOptions: TestOptions.Regular11, expectedOutput: @" In TestMethod In TestMethod ").VerifyIL("C.Main()", @" { // Code size 85 (0x55) .maxstack 2 .locals init (System.Action V_0) //a IL_0000: ldnull IL_0001: stloc.0 IL_0002: ldloc.0 IL_0003: dup IL_0004: brtrue.s IL_0024 IL_0006: pop IL_0007: ldsfld ""System.Action C.<>O.<0>__TestMethod"" IL_000c: dup IL_000d: brtrue.s IL_0022 IL_000f: pop IL_0010: ldnull IL_0011: ldftn ""void C.TestMethod()"" IL_0017: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_001c: dup IL_001d: stsfld ""System.Action C.<>O.<0>__TestMethod"" IL_0022: dup IL_0023: stloc.0 IL_0024: callvirt ""void System.Action.Invoke()"" IL_0029: ldloc.0 IL_002a: dup IL_002b: brtrue.s IL_004f IL_002d: pop IL_002e: ldsfld ""System.Action C.<>c.<>9__0_0"" IL_0033: dup IL_0034: brtrue.s IL_004d IL_0036: pop IL_0037: ldsfld ""C.<>c C.<>c.<>9"" IL_003c: ldftn ""void C.<>c.<Main>b__0_0()"" IL_0042: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0047: dup IL_0048: stsfld ""System.Action C.<>c.<>9__0_0"" IL_004d: dup IL_004e: stloc.0 IL_004f: callvirt ""void System.Action.Invoke()"" IL_0054: ret }"); } [Fact] public void ImplicitlyTypedVariables_01() { var source = @"using System; class Program { static void Main() { var d1 = Main; Report(d1); var d2 = () => { }; Report(d2); var d3 = delegate () { }; Report(d3); } static void Report(Delegate d) => Console.WriteLine($""{d.GetType().Namespace}.{d.GetType().Name}""); }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular11, options: TestOptions.DebugExe); comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, expectedOutput: @"System.Action System.Action System.Action"); verifier.VerifyIL("Program.Main", @" { // Code size 115 (0x73) .maxstack 2 .locals init (System.Action V_0, //d1 System.Action V_1, //d2 System.Action V_2) //d3 IL_0000: nop IL_0001: ldsfld ""System.Action Program.<>O.<0>__Main"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""void Program.Main()"" IL_0011: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""System.Action Program.<>O.<0>__Main"" IL_001c: stloc.0 IL_001d: ldloc.0 IL_001e: call ""void Program.Report(System.Delegate)"" IL_0023: nop IL_0024: ldsfld ""System.Action Program.<>c.<>9__0_0"" IL_0029: dup IL_002a: brtrue.s IL_0043 IL_002c: pop IL_002d: ldsfld ""Program.<>c Program.<>c.<>9"" IL_0032: ldftn ""void Program.<>c.<Main>b__0_0()"" IL_0038: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_003d: dup IL_003e: stsfld ""System.Action Program.<>c.<>9__0_0"" IL_0043: stloc.1 IL_0044: ldloc.1 IL_0045: call ""void Program.Report(System.Delegate)"" IL_004a: nop IL_004b: ldsfld ""System.Action Program.<>c.<>9__0_1"" IL_0050: dup IL_0051: brtrue.s IL_006a IL_0053: pop IL_0054: ldsfld ""Program.<>c Program.<>c.<>9"" IL_0059: ldftn ""void Program.<>c.<Main>b__0_1()"" IL_005f: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_0064: dup IL_0065: stsfld ""System.Action Program.<>c.<>9__0_1"" IL_006a: stloc.2 IL_006b: ldloc.2 IL_006c: call ""void Program.Report(System.Delegate)"" IL_0071: nop IL_0072: ret } "); } [Fact] public void CustomModifiers_Method() { var ilSource = @" .class public auto ansi beforefieldinit C1`1<T> extends System.Object { // Methods .method public hidebysig static string Method () cil managed { // Method begins at RVA 0x2050 // Code size 6 (0x6) .maxstack 8 IL_0000: ldstr ""PASS"" IL_0005: ret } // end of method C1`1::Method .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x2057 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void System.Object::.ctor() IL_0006: ret } // end of method C1`1::.ctor } // end of class C1`1 .class public auto ansi beforefieldinit C2`1<T> extends System.Object { // Methods .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x2057 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void System.Object::.ctor() IL_0006: ret } // end of method C2`1::.ctor } // end of class C2`1 .class public auto ansi beforefieldinit C3`1<T> extends class C1`1<int32 modopt(class C2`1<!T>)> { // Methods .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x205f // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class C1`1<int32>::.ctor() IL_0006: ret } // end of method C3`1::.ctor } // end of class C3`1 "; var source = @" class Test { static void Main() { M<int>(); } static void M<G>() { System.Func<string> x = C3<G>.Method; System.Console.WriteLine(x()); } } "; var compilation = CreateCompilationWithIL(source, ilSource, options: TestOptions.ReleaseExe); var verifier = CompileAndVerify(compilation, expectedOutput: PASS); verifier.VerifyIL("Test.M<G>", @" { // Code size 38 (0x26) .maxstack 2 IL_0000: ldsfld ""System.Func<string> Test.<M>O__1_0<G>.<0>__Method"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""string C1<int>.Method()"" IL_0010: newobj ""System.Func<string>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<string> Test.<M>O__1_0<G>.<0>__Method"" IL_001b: callvirt ""string System.Func<string>.Invoke()"" IL_0020: call ""void System.Console.WriteLine(string)"" IL_0025: ret } "); } [Fact] public void CustomModifiers_Delegate() { var ilSource = @" .class public auto ansi beforefieldinit C1`1<T> extends [mscorlib]System.Object { // Nested Types .class nested public auto ansi sealed F<T> extends [mscorlib]System.MulticastDelegate { // Methods .method public hidebysig specialname rtspecialname instance void .ctor ( object 'object', native int 'method' ) runtime managed { } // end of method F::.ctor .method public hidebysig newslot virtual instance string Invoke () runtime managed { } // end of method F::Invoke .method public hidebysig newslot virtual instance class [mscorlib]System.IAsyncResult BeginInvoke ( class [mscorlib]System.AsyncCallback callback, object 'object' ) runtime managed { } // end of method F::BeginInvoke .method public hidebysig newslot virtual instance string EndInvoke ( class [mscorlib]System.IAsyncResult result ) runtime managed { } // end of method F::EndInvoke } // end of class F // Methods .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x211f // Code size 8 (0x8) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop IL_0007: ret } // end of method C1`1::.ctor } // end of class C1`1 .class public auto ansi beforefieldinit C2`1<T> extends System.Object { // Methods .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x2057 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void System.Object::.ctor() IL_0006: ret } // end of method C2`1::.ctor } // end of class C2`1 .class public auto ansi beforefieldinit C3`1<T> extends class C1`1<int32 modopt(class C2`1<!T>)> { // Methods .method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x205f // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class C1`1<int32>::.ctor() IL_0006: ret } // end of method C3`1::.ctor } // end of class C3`1 "; var source = @" class Test { static void Main() { M<int>(); } static void M<G>() { C3<G>.F x = Method; System.Console.WriteLine(x()); } static string Method() => ""PASS""; } "; static void containerValidator(ModuleSymbol module) { var container = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test.<M>O__1_0"); var field = Assert.Single(container.GetMembers()) as FieldSymbol; Assert.NotNull(field); var typeParameters = new List<TypeParameterSymbol>(); field.Type.VisitType(static (typeSymbol, typeParameters, _) => { if (typeSymbol is TypeParameterSymbol typeParameter) { typeParameters.Add(typeParameter); } return false; }, typeParameters, visitCustomModifiers: true); var typeParameter = Assert.Single(typeParameters); Assert.Equal("G", typeParameter.Name); Assert.Equal("<M>O__1_0", typeParameter.ContainingSymbol.Name); } var compilation = CreateCompilationWithIL(source, ilSource, options: TestOptions.DebugExe); var verifier = CompileAndVerify(compilation, expectedOutput: PASS, symbolValidator: containerValidator); verifier.VerifyIL("Test.M<G>", @" { // Code size 42 (0x2a) .maxstack 2 .locals init (C1<int>.F V_0) //x IL_0000: nop IL_0001: ldsfld ""C1<int>.F Test.<M>O__1_0<G>.<0>__Method"" IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn ""string Test.Method()"" IL_0011: newobj ""C1<int>.F..ctor(object, System.IntPtr)"" IL_0016: dup IL_0017: stsfld ""C1<int>.F Test.<M>O__1_0<G>.<0>__Method"" IL_001c: stloc.0 IL_001d: ldloc.0 IL_001e: callvirt ""string C1<int>.F.Invoke()"" IL_0023: call ""void System.Console.WriteLine(string)"" IL_0028: nop IL_0029: ret } "); } [Fact] public void CompilerLoweringPreserveAttribute_01() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" class Test1 { System.Action M2<[Preserve1][Preserve2]T>() { return (System.Action)D.Target<T>; } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<M2>O__0_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_02() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used class Test1 { void Test() { System.Action local<[Preserve1][Preserve2]T>() { return (System.Action)D.Target<T>; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<local>O__0_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_03() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used class Test1 { void Test<[Preserve1][Preserve2]T>() { System.Action local() { return (System.Action)D.Target<T>; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<Test>O__0_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_04() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used class Test1 { void Test<[Preserve1][Preserve2]T>() { var d = () => { return (System.Action)D.Target<T>; }; } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<Test>O__0_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_05() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" static class Test1 { extension<[Preserve1][Preserve2]T>(int i) { System.Action M2() { return (System.Action)D.Target<T>; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_06() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" static class Test1 { extension(int i) { System.Action M2<[Preserve1][Preserve2]T>() { return (System.Action)D.Target<T>; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<M2>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_07() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used static class Test1 { extension(int i) { void Test() { System.Action local<[Preserve1][Preserve2]T>() { return (System.Action)D.Target<T>; } } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<local>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_08() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used static class Test1 { extension(int i) { void Test<[Preserve1][Preserve2]T>() { System.Action local() { return (System.Action)D.Target<T>; } } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<Test>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_09() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used static class Test1 { extension<[Preserve1][Preserve2]T>(int i) { void Test() { System.Action local() { return (System.Action)D.Target<T>; } } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_10() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used static class Test1 { extension(int i) { void Test<[Preserve1][Preserve2]T>() { var d = () => { return (System.Action)D.Target<T>; }; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<Test>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } [Fact] public void CompilerLoweringPreserveAttribute_11() { string source1 = @" using System; using System.Runtime.CompilerServices; [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve1Attribute : Attribute { } [AttributeUsage(AttributeTargets.GenericParameter)] public class Preserve2Attribute : Attribute { } "; string source2 = @" #pragma warning disable CS8321 // Local function is declared but never used static class Test1 { extension<[Preserve1][Preserve2]T>(int i) { void Test() { var d = () => { return (System.Action)D.Target<T>; }; } } } class D { public static void Target<B>() { } } "; var comp1 = CreateCompilation([source1, source2, CompilerLoweringPreserveAttributeDefinition]); CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); static void validate(ModuleSymbol m) { AssertEx.SequenceEqual( ["Preserve1Attribute"], m.GlobalNamespace.GetMember<NamedTypeSymbol>("Test1.<>O__1_0").TypeParameters.Single().GetAttributes().Select(a => a.ToString())); } } private static Action<ModuleSymbol> VerifyCacheContainer(string typeName, int arity, params string[] expectedFields) { return module => { var container = module.GlobalNamespace.GetMember<NamedTypeSymbol>(typeName); Assert.NotNull(container); Assert.Equal(arity, container.Arity); var fields = container.GetMembers().OfType<FieldSymbol>().Select(field => $"{field.Type.ToTestDisplayString()} {field.Name}").ToArray(); AssertEx.SetEqual(expectedFields, fields); }; } private static Action<ModuleSymbol> VerifyNoCacheContainersIn(string containingTypeName) { return module => { var containingType = module.GlobalNamespace.GetMember<NamedTypeSymbol>(containingTypeName); Assert.NotNull(containingType); var nestedTypes = containingType.GetTypeMembers(); Assert.DoesNotContain(nestedTypes, t => t.Name.StartsWith("<") && t.Name.Contains(">O")); }; } }