Add compiler-generated code tests for NativeAot (#77457)
authorSven Boemer <sbomer@gmail.com>
Mon, 28 Nov 2022 22:43:55 +0000 (14:43 -0800)
committerGitHub <noreply@github.com>
Mon, 28 Nov 2022 22:43:55 +0000 (14:43 -0800)
This adds the compiler-generated code tests from illink and enables them for NativeAot.

Includes fixes in the test infrastructure required to make some of the tests pass.

src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs
src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs [new file with mode: 0644]
src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCodeRelease.cs [new file with mode: 0644]
src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs

index ec237817f2901f94580f26811318de71cdbb4783..1e6202665c685f1670ef5c35f452ed674a047097 100644 (file)
@@ -8,6 +8,7 @@
     <DefineConstants>$(DefineConstants);INCLUDE_EXPECTATIONS</DefineConstants>
     <WarningLevel>0</WarningLevel>
     <AnalysisLevel>0</AnalysisLevel>
+    <RunAnalyzers>true</RunAnalyzers>
   </PropertyGroup>
 
   <ItemGroup>
index b89dfc61e8cf3cdcb953715695964719a7701721..25275f426c56bc37fc1991afe8e007d4ea137b28 100644 (file)
@@ -188,12 +188,9 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability
                                public static void GenericTypeWithStaticMethodWhichRequires () { }
                        }
 
-                       // NativeAOT doesnt produce Requires warnings in Generics https://github.com/dotnet/runtime/issues/68688
-                       // [ExpectedWarning("IL2026", "--GenericTypeWithStaticMethodWhichRequires--"]
-                       [ExpectedWarning ("IL2026", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.Trimmer)]
-                       // [ExpectedWarning("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
                        [ExpectedWarning ("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer)]
-                       // [ExpectedWarning("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
                        [ExpectedWarning ("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer)]
                        public static void GenericTypeWithStaticMethodViaLdftn ()
                        {
diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs
new file mode 100644 (file)
index 0000000..f77d373
--- /dev/null
@@ -0,0 +1,2284 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Threading.Tasks;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.RequiresCapability
+{
+       [SkipKeptItemsValidation]
+       [ExpectedNoWarnings]
+       public class RequiresInCompilerGeneratedCode
+       {
+               public static void Main ()
+               {
+                       WarnInIteratorBody.Test ();
+                       SuppressInIteratorBody.Test ();
+
+                       WarnInAsyncBody.Test ();
+                       SuppressInAsyncBody.Test ();
+
+                       WarnInAsyncIteratorBody.Test ();
+                       SuppressInAsyncIteratorBody.Test ();
+
+                       WarnInLocalFunction.Test ();
+                       SuppressInLocalFunction.Test ();
+                       WarnInNonNestedLocalFunctionTest ();
+                       SuppressInNonNestedLocalFunctionTest ();
+
+                       WarnInLambda.Test ();
+                       SuppressInLambda.Test ();
+
+                       WarnInComplex.Test ();
+                       SuppressInComplex.Test ();
+
+                       StateMachinesOnlyReferencedViaReflection.Test ();
+                       LocalFunctionsReferencedViaReflection.Test ();
+                       LambdasReferencedViaReflection.Test ();
+
+                       ComplexCases.AsyncBodyCallingMethodWithRequires.Test ();
+                       ComplexCases.GenericAsyncBodyCallingMethodWithRequires.Test ();
+                       ComplexCases.GenericAsyncEnumerableBodyCallingRequiresWithAnnotations.Test ();
+               }
+
+               class WarnInIteratorBody
+               {
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestCallBeforeYieldReturn ()
+                       {
+                               MethodWithRequires ();
+                               yield return 0;
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestCallAfterYieldReturn ()
+                       {
+                               yield return 0;
+                               MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestReflectionAccess ()
+                       {
+                               yield return 0;
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               yield return 1;
+                       }
+
+#if !RELEASE
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)]
+#else
+                       // In release mode, the compiler optimizes away the unused Action (and reference to MethodWithRequires)
+#endif
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static IEnumerable<int> TestLdftn ()
+                       {
+                               yield return 0;
+                               yield return 1;
+                               var action = new Action (MethodWithRequires);
+                       }
+
+                       // Cannot annotate fields either with RUC nor RAF therefore the warning persists
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static IEnumerable<int> TestLazyDelegate ()
+                       {
+                               yield return 0;
+                               yield return 1;
+                               _ = _default.Value;
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               yield return 0;
+                               yield return 1;
+                       }
+
+                       public static void Test ()
+                       {
+                               TestCallBeforeYieldReturn ();
+                               TestCallAfterYieldReturn ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                       }
+               }
+
+               class SuppressInIteratorBody
+               {
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestCall ()
+                       {
+                               MethodWithRequires ();
+                               yield return 0;
+                               MethodWithRequires ();
+                               yield return 1;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestReflectionAccess ()
+                       {
+                               yield return 0;
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               yield return 1;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestLdftn ()
+                       {
+                               yield return 0;
+                               yield return 1;
+                               var action = new Action (MethodWithRequires);
+                       }
+
+                       // Cannot annotate fields either with RUC nor RAF therefore the warning persists
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static IEnumerable<int> TestLazyDelegate ()
+                       {
+                               yield return 0;
+                               yield return 1;
+                               _ = _default.Value;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               yield return 0;
+                               yield return 1;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestMethodParameterWithRequirements (Type unknownType = null)
+                       {
+                               unknownType.RequiresNonPublicMethods ();
+                               yield return 0;
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestGenericMethodParameterRequirement<TUnknown> ()
+                       {
+                               MethodWithGenericWhichRequiresMethods<TUnknown> ();
+                               yield return 0;
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestGenericTypeParameterRequirement<TUnknown> ()
+                       {
+                               new TypeWithGenericWhichRequiresNonPublicFields<TUnknown> ();
+                               yield return 0;
+                       }
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                               TestMethodParameterWithRequirements ();
+                               TestGenericMethodParameterRequirement<TestType> ();
+                               TestGenericTypeParameterRequirement<TestType> ();
+                       }
+               }
+
+               class WarnInAsyncBody
+               {
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static async void TestCallBeforeYieldReturn ()
+                       {
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static async void TestCallAfterYieldReturn ()
+                       {
+                               await MethodAsync ();
+                               MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static async void TestReflectionAccess ()
+                       {
+                               await MethodAsync ();
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               await MethodAsync ();
+                       }
+
+#if !RELEASE
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)]
+#endif
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static async void TestLdftn ()
+                       {
+                               await MethodAsync ();
+                               var action = new Action (MethodWithRequires);
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static async void TestLazyDelegate ()
+                       {
+                               await MethodAsync ();
+                               _ = _default.Value;
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static async void TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               await MethodAsync ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestCallBeforeYieldReturn ();
+                               TestCallAfterYieldReturn ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                       }
+               }
+
+               class SuppressInAsyncBody
+               {
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestCall ()
+                       {
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestReflectionAccess ()
+                       {
+                               await MethodAsync ();
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               await MethodAsync ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestLdftn ()
+                       {
+                               await MethodAsync ();
+                               var action = new Action (MethodWithRequires);
+                       }
+
+                       // Cannot annotate fields either with RUC nor RAF therefore the warning persists
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static async void TestLazyDelegate ()
+                       {
+                               await MethodAsync ();
+                               _ = _default.Value;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               await MethodAsync ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestMethodParameterWithRequirements (Type unknownType = null)
+                       {
+                               unknownType.RequiresNonPublicMethods ();
+                               await MethodAsync ();
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestGenericMethodParameterRequirement<TUnknown> ()
+                       {
+                               MethodWithGenericWhichRequiresMethods<TUnknown> ();
+                               await MethodAsync ();
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestGenericTypeParameterRequirement<TUnknown> ()
+                       {
+                               new TypeWithGenericWhichRequiresNonPublicFields<TUnknown> ();
+                               await MethodAsync ();
+                       }
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                               TestMethodParameterWithRequirements ();
+                               TestGenericMethodParameterRequirement<TestType> ();
+                               TestGenericTypeParameterRequirement<TestType> ();
+                       }
+               }
+
+               class WarnInAsyncIteratorBody
+               {
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static async IAsyncEnumerable<int> TestCallBeforeYieldReturn ()
+                       {
+                               await MethodAsync ();
+                               MethodWithRequires ();
+                               yield return 0;
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static async IAsyncEnumerable<int> TestCallAfterYieldReturn ()
+                       {
+                               yield return 0;
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static async IAsyncEnumerable<int> TestReflectionAccess ()
+                       {
+                               yield return 0;
+                               await MethodAsync ();
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               await MethodAsync ();
+                               yield return 1;
+                       }
+
+#if !RELEASE
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)]
+#endif
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static async IAsyncEnumerable<int> TestLdftn ()
+                       {
+                               await MethodAsync ();
+                               yield return 0;
+                               var action = new Action (MethodWithRequires);
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static async IAsyncEnumerable<int> TestLazyDelegate ()
+                       {
+                               await MethodAsync ();
+                               yield return 0;
+                               _ = _default.Value;
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static async IAsyncEnumerable<int> TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               yield return 0;
+                               await MethodAsync ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestCallBeforeYieldReturn ();
+                               TestCallAfterYieldReturn ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                       }
+               }
+
+               class SuppressInAsyncIteratorBody
+               {
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestCall ()
+                       {
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                               yield return 0;
+                               MethodWithRequires ();
+                               await MethodAsync ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestReflectionAccess ()
+                       {
+                               await MethodAsync ();
+                               yield return 0;
+                               typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                               await MethodAsync ();
+                               yield return 0;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestLdftn ()
+                       {
+                               await MethodAsync ();
+                               var action = new Action (MethodWithRequires);
+                               yield return 0;
+                       }
+
+                       // Cannot annotate fields either with RUC nor RAF therefore the warning persists
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static async IAsyncEnumerable<int> TestLazyDelegate ()
+                       {
+                               await MethodAsync ();
+                               yield return 0;
+                               _ = _default.Value;
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestDynamicallyAccessedMethod ()
+                       {
+                               typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               yield return 0;
+                               await MethodAsync ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestMethodParameterWithRequirements (Type unknownType = null)
+                       {
+                               unknownType.RequiresNonPublicMethods ();
+                               await MethodAsync ();
+                               yield return 0;
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestGenericMethodParameterRequirement<TUnknown> ()
+                       {
+                               yield return 0;
+                               MethodWithGenericWhichRequiresMethods<TUnknown> ();
+                               await MethodAsync ();
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async IAsyncEnumerable<int> TestGenericTypeParameterRequirement<TUnknown> ()
+                       {
+                               new TypeWithGenericWhichRequiresNonPublicFields<TUnknown> ();
+                               yield return 0;
+                               await MethodAsync ();
+                       }
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                               TestMethodParameterWithRequirements ();
+                               TestGenericMethodParameterRequirement<TestType> ();
+                               TestGenericTypeParameterRequirement<TestType> ();
+                       }
+               }
+
+               class WarnInLocalFunction
+               {
+                       static void TestCall ()
+                       {
+                               LocalFunction ();
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--LocalFunctionWithRequires--")]
+                       [ExpectedWarning ("IL3002", "--LocalFunctionWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--LocalFunctionWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestLocalFunctionWithRequires ()
+                       {
+                               LocalFunction ();
+
+                               [RequiresUnreferencedCode ("--LocalFunctionWithRequires--")]
+                               [RequiresAssemblyFiles ("--LocalFunctionWithRequires--")]
+                               [RequiresDynamicCode ("--LocalFunctionWithRequires--")]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       static void TestCallUnused ()
+                       {
+                               // Analyzer emits warnings for code in unused local functions.
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       static void TestCallWithClosure (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               void LocalFunction ()
+                               {
+                                       p++;
+                                       MethodWithRequires ();
+                               }
+                       }
+
+                       static void TestCallWithClosureUnused (int p = 0)
+                       {
+                               // Analyzer emits warnings for code in unused local functions.
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               void LocalFunction ()
+                               {
+                                       p++;
+                                       MethodWithRequires ();
+                               }
+                       }
+
+                       static void TestReflectionAccess ()
+                       {
+                               LocalFunction ();
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               void LocalFunction () => typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                       }
+
+                       static void TestLdftn ()
+                       {
+                               LocalFunction ();
+
+#if !RELEASE
+                               // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+#endif
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               void LocalFunction ()
+                               {
+                                       var action = new Action (MethodWithRequires);
+                               }
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static void TestLazyDelegate ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       _ = _default.Value;
+                               }
+                       }
+
+                       static void TestDynamicallyAccessedMethod ()
+                       {
+                               LocalFunction ();
+
+                               [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")]
+                               void LocalFunction () => typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestLocalFunctionWithRequires ();
+                               TestCallUnused ();
+                               TestCallWithClosure ();
+                               TestCallWithClosureUnused ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                       }
+               }
+
+               class SuppressInLocalFunction
+               {
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCall ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallFromNestedLocalFunction ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       NestedLocalFunction ();
+
+                                       void NestedLocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallWithClosure (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       p++;
+                                       MethodWithRequires ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestReflectionAccess ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => typeof (RequiresInCompilerGeneratedCode)
+                                       .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                       .Invoke (null, new object[] { });
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestLdftn ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       var action = new Action (MethodWithRequires);
+                               }
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Message from --MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Message from --MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static void TestLazyDelegate ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       _ = _default.Value;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestDynamicallyAccessedMethod ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestMethodParameterWithRequirements (Type unknownType = null)
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => unknownType.RequiresNonPublicMethods ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericMethodParameterRequirement<TUnknown> ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => MethodWithGenericWhichRequiresMethods<TUnknown> ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericTypeParameterRequirement<TUnknown> ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => new TypeWithGenericWhichRequiresNonPublicFields<TUnknown> ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericLocalFunction<TUnknown> ()
+                       {
+                               LocalFunction<TUnknown> ();
+
+                               void LocalFunction<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ()
+                               {
+                                       typeof (T).RequiresPublicMethods ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericLocalFunctionInner<TUnknown> ()
+                       {
+                               LocalFunction<TUnknown> ();
+
+                               void LocalFunction<TSecond> ()
+                               {
+                                       typeof (TUnknown).RequiresPublicMethods ();
+                                       typeof (TSecond).RequiresPublicMethods ();
+                               }
+                       }
+
+                       static void TestGenericLocalFunctionWithAnnotations<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> ()
+                       {
+                               LocalFunction<TPublicMethods> ();
+
+                               void LocalFunction<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TInnerPublicMethods> ()
+                               {
+                                       typeof (TPublicMethods).RequiresPublicMethods ();
+                                       typeof (TInnerPublicMethods).RequiresPublicMethods ();
+                               }
+                       }
+
+                       static void TestGenericLocalFunctionWithAnnotationsAndClosure<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> (int p = 0)
+                       {
+                               LocalFunction<TPublicMethods> ();
+
+                               void LocalFunction<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TInnerPublicMethods> ()
+                               {
+                                       p++;
+                                       typeof (TPublicMethods).RequiresPublicMethods ();
+                                       typeof (TInnerPublicMethods).RequiresPublicMethods ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallMethodWithRequiresInLtftnLocalFunction ()
+                       {
+                               var _ = new Action (LocalFunction);
+
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       class DynamicallyAccessedLocalFunction
+                       {
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ()
+                               {
+                                       typeof (DynamicallyAccessedLocalFunction).RequiresNonPublicMethods ();
+
+                                       LocalFunction ();
+
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       class DynamicallyAccessedLocalFunctionUnusedShouldWarn
+                       {
+                               // https://github.com/dotnet/runtime/issues/68786
+                               [ExpectedWarning ("IL2118", nameof (TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction), "LocalFunction", ProducedBy = ProducedBy.Trimmer)]
+                               public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ()
+                               {
+                                       typeof (DynamicallyAccessedLocalFunctionUnusedShouldWarn).RequiresNonPublicMethods ();
+
+                                       // The linker isn't able to figure out which user method this local function
+                                       // belongs to, but it doesn't warn because it is only accessed via reflection.
+                                       // Instead this warns on the reflection access.
+                                       [ExpectedWarning ("IL2026", "--MethodWithRequires--",
+                                               ProducedBy = ProducedBy.Analyzer)]
+                                       [ExpectedWarning ("IL3002", "--MethodWithRequires--",
+                                               ProducedBy = ProducedBy.Analyzer)]
+                                       [ExpectedWarning ("IL3050", "--MethodWithRequires--",
+                                               ProducedBy = ProducedBy.Analyzer)]
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       class DynamicallyAccessedLocalFunctionUnusedShouldSuppress
+                       {
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ()
+                               {
+                                       typeof (DynamicallyAccessedLocalFunctionUnusedShouldSuppress).RequiresNonPublicMethods ();
+
+                                       // The linker isn't able to figure out which user method this local function
+                                       // belongs to, but it doesn't warn because it is only accessed via reflection,
+                                       // in a RUC scope.
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       [ExpectedWarning ("IL2026")]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestSuppressionOnLocalFunction ()
+                       {
+                               LocalFunction (); // This will produce a warning since the local function has Requires on it
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               void LocalFunction (Type unknownType = null)
+                               {
+                                       MethodWithRequires ();
+                                       unknownType.RequiresNonPublicMethods ();
+                               }
+                       }
+
+                       [ExpectedWarning ("IL2026")]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestSuppressionOnLocalFunctionWithAssignment ()
+                       {
+                               LocalFunction (); // This will produce a warning since the local function has Requires on it
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               void LocalFunction (Type unknownType = null)
+                               {
+                                       MethodWithRequires ();
+                                       typeWithNonPublicMethods = unknownType;
+                               }
+                       }
+
+                       [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)]
+                       static Type typeWithNonPublicMethods;
+
+                       [ExpectedWarning ("IL2026")]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestSuppressionOnLocalFunctionWithNestedLocalFunction ()
+                       {
+                               LocalFunction (); // This will produce a warning since the local function has Requires on it
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               void LocalFunction ()
+                               {
+                                       NestedLocalFunction ();
+
+                                       // The linker doesn't have enough information to associate the Requires on LocalFunction
+                                       // with this nested local function.
+                                       [ExpectedWarning ("IL2026", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.NativeAot)]
+                                       void NestedLocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestSuppressionOnOuterAndLocalFunction ()
+                       {
+                               LocalFunction ();
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               void LocalFunction (Type unknownType = null)
+                               {
+                                       MethodWithRequires ();
+                                       unknownType.RequiresNonPublicMethods ();
+                               }
+                       }
+
+                       class TestSuppressionOnOuterWithSameName
+                       {
+                               [ExpectedWarning ("IL2026", nameof (Outer) + "()")]
+                               [ExpectedWarning ("IL3002", nameof (Outer) + "()", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", nameof (Outer) + "()", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               public static void Test ()
+                               {
+                                       Outer ();
+                                       Outer (0);
+                               }
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               static void Outer ()
+                               {
+                                       // Even though this method has the same name as Outer(int i),
+                                       // it should not suppress warnings originating from compiler-generated
+                                       // code for the lambda contained in Outer(int i).
+                               }
+
+                               static void Outer (int i)
+                               {
+                                       LocalFunction ();
+
+                                       [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestCallFromNestedLocalFunction ();
+                               TestCallWithClosure ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestMethodParameterWithRequirements ();
+                               TestDynamicallyAccessedMethod ();
+                               TestGenericMethodParameterRequirement<TestType> ();
+                               TestGenericTypeParameterRequirement<TestType> ();
+                               TestGenericLocalFunction<TestType> ();
+                               TestGenericLocalFunctionInner<TestType> ();
+                               TestGenericLocalFunctionWithAnnotations<TestType> ();
+                               TestGenericLocalFunctionWithAnnotationsAndClosure<TestType> ();
+                               TestCallMethodWithRequiresInLtftnLocalFunction ();
+                               DynamicallyAccessedLocalFunction.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ();
+                               DynamicallyAccessedLocalFunctionUnusedShouldWarn.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ();
+                               DynamicallyAccessedLocalFunctionUnusedShouldSuppress.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction ();
+                               TestSuppressionOnLocalFunction ();
+                               TestSuppressionOnLocalFunctionWithAssignment ();
+                               TestSuppressionOnLocalFunctionWithNestedLocalFunction ();
+                               TestSuppressionOnOuterAndLocalFunction ();
+                               TestSuppressionOnOuterWithSameName.Test ();
+                       }
+               }
+
+               static void WarnInNonNestedLocalFunctionTest ()
+               {
+                       LocalFunction ();
+
+                       [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void LocalFunction () => MethodWithRequires ();
+               }
+
+               [ExpectedWarning ("IL2026", "--MethodWithNonNestedLocalFunction--")]
+               [ExpectedWarning ("IL3002", "--MethodWithNonNestedLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+               [ExpectedWarning ("IL3050", "--MethodWithNonNestedLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+               static void SuppressInNonNestedLocalFunctionTest ()
+               {
+                       MethodWithNonNestedLocalFunction ();
+               }
+
+               [RequiresUnreferencedCode ("--MethodWithNonNestedLocalFunction--")]
+               [RequiresAssemblyFiles ("--MethodWithNonNestedLocalFunction--")]
+               [RequiresDynamicCode ("--MethodWithNonNestedLocalFunction--")]
+               static void MethodWithNonNestedLocalFunction ()
+               {
+                       LocalFunction ();
+
+                       static void LocalFunction () => MethodWithRequires ();
+               }
+
+               class WarnInLambda
+               {
+                       static void TestCall ()
+                       {
+                               Action lambda =
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               () => MethodWithRequires ();
+
+                               lambda ();
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--LambdaWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestLambdaWithRequires ()
+                       {
+                               Action lambda =
+                                       [RequiresUnreferencedCodeAttribute ("--LambdaWithRequires--")]
+                               [RequiresAssemblyFiles ("--LambdaWithRequires--")]
+                               [RequiresDynamicCode ("--LambdaWithRequires--")]
+                               () => MethodWithRequires ();
+
+                               lambda ();
+                       }
+
+                       static void TestCallUnused ()
+                       {
+                               Action _ =
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               () => MethodWithRequires ();
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--LambdaWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestLambdaWithRequiresUnused ()
+                       {
+                               Action _ =
+                                       [RequiresUnreferencedCode ("--LambdaWithRequires--")]
+                               [RequiresAssemblyFiles ("--LambdaWithRequires--")]
+                               [RequiresDynamicCode ("--LambdaWithRequires--")]
+                               () => MethodWithRequires ();
+                       }
+
+                       static void TestCallWithClosure (int p = 0)
+                       {
+                               Action lambda =
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               () => {
+                                       p++;
+                                       MethodWithRequires ();
+                               };
+
+                               lambda ();
+                       }
+
+                       static void TestCallWithClosureUnused (int p = 0)
+                       {
+                               Action _ =
+#if !RELEASE
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.NativeAot)]
+#endif
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               () => {
+                                       p++;
+                                       MethodWithRequires ();
+                               };
+                       }
+
+                       static void TestReflectionAccess ()
+                       {
+                               Action _ =
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               () => {
+                                       typeof (RequiresInCompilerGeneratedCode)
+                                               .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                               .Invoke (null, new object[] { });
+                               };
+                       }
+
+                       static void TestLdftn ()
+                       {
+                               Action _ =
+#if !RELEASE
+                               // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+#endif
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                               () => {
+                                       var action = new Action (MethodWithRequires);
+                               };
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static void TestLazyDelegate ()
+                       {
+                               Action _ = () => {
+                                       var action = _default.Value;
+                               };
+                       }
+
+                       static void TestDynamicallyAccessedMethod ()
+                       {
+                               Action _ =
+                               [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--")]
+                               () => {
+                                       typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               };
+                       }
+
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestCallUnused ();
+                               TestLambdaWithRequires ();
+                               TestLambdaWithRequiresUnused ();
+                               TestCallWithClosure ();
+                               TestCallWithClosureUnused ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                       }
+               }
+
+               class SuppressInLambda
+               {
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCall ()
+                       {
+                               Action _ =
+                               () => MethodWithRequires ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallFromNestedLambda ()
+                       {
+                               Action lambda = () => {
+                                       Action nestedLambda = () => MethodWithRequires ();
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallWithReflectionAnalysisWarning ()
+                       {
+                               // This should not produce warning because the Requires
+                               Action<Type> _ =
+                               (t) => t.RequiresPublicMethods ();
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallWithClosure (int p = 0)
+                       {
+                               Action _ =
+                               () => {
+                                       p++;
+                                       MethodWithRequires ();
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestReflectionAccess ()
+                       {
+                               Action _ =
+                               () => {
+                                       typeof (RequiresInCompilerGeneratedCode)
+                                               .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic)
+                                               .Invoke (null, new object[] { });
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestLdftn ()
+                       {
+                               Action _ =
+                               () => {
+                                       var action = new Action (MethodWithRequires);
+                               };
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--MethodWithRequiresAndReturns--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--MethodWithRequiresAndReturns--", ProducedBy = ProducedBy.Analyzer)]
+                       public static Lazy<string> _default = new Lazy<string> (MethodWithRequiresAndReturns);
+
+                       static void TestLazyDelegate ()
+                       {
+                               Action _ = () => {
+                                       var action = _default.Value;
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestDynamicallyAccessedMethod ()
+                       {
+                               Action _ =
+                               () => {
+                                       typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods ();
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestMethodParameterWithRequirements (Type unknownType = null)
+                       {
+                               Action _ =
+                               () => unknownType.RequiresNonPublicMethods ();
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericMethodParameterRequirement<TUnknown> ()
+                       {
+                               Action _ =
+                               () => {
+                                       MethodWithGenericWhichRequiresMethods<TUnknown> ();
+                               };
+                       }
+
+                       // https://github.com/dotnet/runtime/issues/68688
+                       // This test passes on NativeAot even without the Requires* attributes.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestGenericTypeParameterRequirement<TUnknown> ()
+                       {
+                               Action _ = () => {
+                                       new TypeWithGenericWhichRequiresNonPublicFields<TUnknown> ();
+                               };
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestSuppressionOnLambda ()
+                       {
+                               var lambda =
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               () => MethodWithRequires ();
+
+                               lambda (); // This will produce a warning since the lambda has Requires on it
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestSuppressionOnLambdaWithNestedLambda ()
+                       {
+                               var lambda =
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               () => {
+                                       // The linker doesn't try to associate the Requires on lambda with this nested
+                                       // lambda. It would be possible to do this because the declaration site will contain
+                                       // an IL reference to the generated lambda method, unlike local functions.
+                                       // However, we don't make this association, for consistency with local functions.
+                                       var nestedLambda =
+                                       [ExpectedWarning ("IL2026", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.NativeAot)]
+                                       () => MethodWithRequires ();
+                               };
+
+                               lambda (); // This will produce a warning since the lambda has Requires on it
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestSuppressionOnOuterAndLambda ()
+                       {
+                               var lambda =
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               (Type unknownType) => {
+                                       MethodWithRequires ();
+                                       unknownType.RequiresNonPublicMethods ();
+                               };
+
+                               lambda (null);
+                       }
+
+                       class TestSuppressionOnOuterWithSameName
+                       {
+                               [ExpectedWarning ("IL2026", nameof (Outer) + "()")]
+                               [ExpectedWarning ("IL3002", nameof (Outer) + "()", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", nameof (Outer) + "()", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               public static void Test ()
+                               {
+                                       Outer ();
+                                       Outer (0);
+                               }
+
+                               [RequiresUnreferencedCode ("Suppress in body")]
+                               [RequiresAssemblyFiles ("Suppress in body")]
+                               [RequiresDynamicCode ("Suppress in body")]
+                               static void Outer ()
+                               {
+                                       // Even though this method has the same name as Outer(int i),
+                                       // it should not suppress warnings originating from compiler-generated
+                                       // code for the lambda contained in Outer(int i).
+                               }
+
+                               static void Outer (int i)
+                               {
+                                       var lambda =
+                                       [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       () => MethodWithRequires ();
+
+                                       lambda ();
+                               }
+                       }
+
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestCall ();
+                               TestCallFromNestedLambda ();
+                               TestCallWithReflectionAnalysisWarning ();
+                               TestCallWithClosure ();
+                               TestReflectionAccess ();
+                               TestLdftn ();
+                               TestLazyDelegate ();
+                               TestDynamicallyAccessedMethod ();
+                               TestMethodParameterWithRequirements ();
+                               TestGenericMethodParameterRequirement<TestType> ();
+                               TestGenericTypeParameterRequirement<TestType> ();
+                               TestSuppressionOnLambda ();
+                               TestSuppressionOnLambdaWithNestedLambda ();
+                               TestSuppressionOnOuterAndLambda ();
+                               TestSuppressionOnOuterWithSameName.Test ();
+                       }
+               }
+
+               class WarnInComplex
+               {
+                       static async void TestIteratorLocalFunctionInAsync ()
+                       {
+                               await MethodAsync ();
+                               LocalFunction ();
+                               await MethodAsync ();
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       yield return 0;
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+                       }
+
+#if !NATIVEAOT
+                       // BUG: https://github.com/dotnet/runtime/issues/77455
+                       // NativeAot produces an incorrect warning pointing to the InstantiatedMethod, which isn't associated
+                       // with the calling context.
+                       [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator ()
+                       {
+                               yield return 1;
+                               MethodWithGenericWhichRequiresMethods<TypeWithMethodWithRequires> ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestDynamicallyAccessedMethodViaGenericTypeParameterInIterator ()
+                       {
+                               yield return 1;
+                               new TypeWithGenericWhichRequiresMethods<TypeWithMethodWithRequires> ();
+                       }
+#endif
+
+                       static void TestLocalFunctionInIteratorLocalFunction ()
+                       {
+                               IteratorLocalFunction ();
+
+                               IEnumerable<int> IteratorLocalFunction ()
+                               {
+                                       yield return 0;
+                                       LocalFunction ();
+                                       yield return 1;
+
+                                       [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       static void TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod ()
+                       {
+                               IteratorLocalFunction ();
+
+                               IEnumerable<int> IteratorLocalFunction ()
+                               {
+                                       yield return 0;
+                                       LocalFunction ();
+                                       yield return 1;
+                               }
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestIteratorLocalFunctionInAsync ();
+#if !NATIVEAOT
+                               TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator ();
+                               TestDynamicallyAccessedMethodViaGenericTypeParameterInIterator ();
+#endif
+                               TestLocalFunctionInIteratorLocalFunction ();
+                               TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod ();
+                       }
+               }
+
+               class SuppressInComplex
+               {
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestIteratorLocalFunction ()
+                       {
+                               LocalFunction ();
+
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       yield return 0;
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestAsyncLocalFunction ()
+                       {
+                               LocalFunction ();
+
+                               async Task<int> LocalFunction ()
+                               {
+                                       await MethodAsync ();
+                                       MethodWithRequires ();
+                                       return 1;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestIteratorLocalFunctionWithClosure (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       p++;
+                                       yield return 0;
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestAsyncLocalFunctionWithClosure (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               async Task<int> LocalFunction ()
+                               {
+                                       p++;
+                                       await MethodAsync ();
+                                       MethodWithRequires ();
+                                       return 1;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestCallToLocalFunctionInIteratorLocalFunctionWithClosure (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       p++;
+                                       yield return 0;
+                                       LocalFunction2 ();
+                                       yield return 1;
+
+                                       void LocalFunction2 ()
+                                       {
+                                               MethodWithRequires ();
+                                       }
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestAsyncLambda ()
+                       {
+                               Func<Task<int>> _ = async Task<int> () => {
+                                       await MethodAsync ();
+                                       MethodWithRequires ();
+                                       return 1;
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestAsyncLambdaWithClosure (int p = 0)
+                       {
+                               Func<Task<int>> _ = async Task<int> () => {
+                                       p++;
+                                       await MethodAsync ();
+                                       MethodWithRequires ();
+                                       return 1;
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static void TestLambdaInAsyncLambdaWithClosure (int p = 0)
+                       {
+                               Func<Task<int>> _ = async Task<int> () => {
+                                       p++;
+                                       await MethodAsync ();
+                                       var lambda = () => MethodWithRequires ();
+                                       return 1;
+                               };
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestIteratorLocalFunctionInAsync ()
+                       {
+                               await MethodAsync ();
+                               LocalFunction ();
+                               await MethodAsync ();
+
+                               [RequiresUnreferencedCode ("Suppress in local function")]
+                               [RequiresAssemblyFiles ("Suppress in local function")]
+                               [RequiresDynamicCode ("Suppress in local function")]
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       yield return 0;
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static async void TestIteratorLocalFunctionInAsyncWithoutInner ()
+                       {
+                               await MethodAsync ();
+                               LocalFunction ();
+                               await MethodAsync ();
+
+                               IEnumerable<int> LocalFunction ()
+                               {
+                                       yield return 0;
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+                       }
+
+#if !NATIVEAOT
+                       // BUG: https://github.com/dotnet/runtime/issues/77455
+                       // NativeAot produces an incorrect warning pointing to the InstantiatedMethod, which isn't associated
+                       // with the calling context.
+                       [RequiresUnreferencedCode ("Suppress in body")]
+                       [RequiresAssemblyFiles ("Suppress in body")]
+                       [RequiresDynamicCode ("Suppress in body")]
+                       static IEnumerable<int> TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator ()
+                       {
+                               MethodWithGenericWhichRequiresMethods<TypeWithMethodWithRequires> ();
+                               yield return 0;
+                       }
+#endif
+
+                       [ExpectedWarning ("IL2026", "--IteratorLocalFunction--")]
+                       [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestLocalFunctionInIteratorLocalFunction ()
+                       {
+                               IteratorLocalFunction ();
+
+                               [RequiresUnreferencedCode ("--IteratorLocalFunction--")]
+                               [RequiresAssemblyFiles ("--IteratorLocalFunction--")]
+                               [RequiresDynamicCode ("--IteratorLocalFunction--")]
+                               IEnumerable<int> IteratorLocalFunction ()
+                               {
+                                       yield return 0;
+                                       LocalFunction ();
+                                       MethodWithRequires ();
+                                       yield return 1;
+
+                                       // Trimmer doesn't try to associate LocalFunction with IteratorLocalFunction
+                                       [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.NativeAot)]
+                                       [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.NativeAot)]
+                                       void LocalFunction () => MethodWithRequires ();
+                               }
+                       }
+
+                       [ExpectedWarning ("IL2026", "--IteratorLocalFunction--")]
+                       [ExpectedWarning ("IL3002", "--IteratorLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--IteratorLocalFunction--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod ()
+                       {
+                               IteratorLocalFunction ();
+                               LocalFunction ();
+
+                               [RequiresUnreferencedCode ("--IteratorLocalFunction--")]
+                               [RequiresAssemblyFiles ("--IteratorLocalFunction--")]
+                               [RequiresDynamicCode ("--IteratorLocalFunction--")]
+                               IEnumerable<int> IteratorLocalFunction ()
+                               {
+                                       yield return 0;
+                                       LocalFunction ();
+                                       MethodWithRequires ();
+                                       yield return 1;
+                               }
+
+                               [ExpectedWarning ("IL2026", "--MethodWithRequires--")]
+                               [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [UnconditionalSuppressMessage ("Trimming", "IL2026")]
+                       [UnconditionalSuppressMessage ("SingleFile", "IL3002")]
+                       [UnconditionalSuppressMessage ("AOT", "IL3050")]
+                       public static void Test ()
+                       {
+                               TestIteratorLocalFunction ();
+                               TestAsyncLocalFunction ();
+                               TestIteratorLocalFunctionWithClosure ();
+                               TestAsyncLocalFunctionWithClosure ();
+                               TestCallToLocalFunctionInIteratorLocalFunctionWithClosure ();
+                               TestAsyncLambda ();
+                               TestAsyncLambdaWithClosure ();
+                               TestLambdaInAsyncLambdaWithClosure ();
+                               TestIteratorLocalFunctionInAsync ();
+                               TestIteratorLocalFunctionInAsyncWithoutInner ();
+#if !NATIVEAOT
+                               TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator ();
+#endif
+                               TestLocalFunctionInIteratorLocalFunction ();
+                               TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod ();
+                       }
+               }
+
+               class StateMachinesOnlyReferencedViaReflection
+               {
+                       [RequiresUnreferencedCode ("--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [RequiresAssemblyFiles ("--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [RequiresDynamicCode ("--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       static IEnumerable<int> TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress ()
+                       {
+                               yield return 0;
+                               MethodWithRequires ();
+                       }
+
+                       [RequiresUnreferencedCode ("--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [RequiresAssemblyFiles ("--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [RequiresDynamicCode ("--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       static async void TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress ()
+                       {
+                               await MethodAsync ();
+                               MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static IEnumerable<int> TestIteratorOnlyReferencedViaReflectionWhichShouldWarn ()
+                       {
+                               yield return 0;
+                               MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot, CompilerGeneratedCode = true)]
+                       static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn ()
+                       {
+                               await MethodAsync ();
+                               MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [ExpectedWarning ("IL2026", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       // Analyzer doesn't emit additional warnings about reflection access to the compiler-generated
+                       // state machine members.
+                       [ExpectedWarning ("IL2026", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = ProducedBy.Trimmer)]
+#if !RELEASE
+                       [ExpectedWarning ("IL2026", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--", ProducedBy = ProducedBy.Trimmer)]
+                       // In debug mode, the async state machine is a class with a constructor, so a warning is emitted for the constructor.
+                       // The MoveNext method is virtual, so doesn't warn either way.
+#else
+                       // In release mode, the async state machine is a struct which doesn't have a constructor, so no warning is emitted.
+#endif
+                       // Linker warns about reflection access to compiler-generated state machine members.
+                       // https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()",
+                               ProducedBy = ProducedBy.Trimmer)]
+                       [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()",
+                               ProducedBy = ProducedBy.Trimmer)]
+                       static void TestAll ()
+                       {
+                               typeof (StateMachinesOnlyReferencedViaReflection).RequiresAll ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "--TestIteratorOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       [ExpectedWarning ("IL2026", "--TestAsyncOnlyReferencedViaReflectionWhichShouldSuppress--")]
+                       // NonPublicMethods doesn't warn for members emitted into compiler-generated state machine types.
+                       static void TestNonPublicMethods ()
+                       {
+                               typeof (StateMachinesOnlyReferencedViaReflection).RequiresNonPublicMethods ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestAll ();
+                               TestNonPublicMethods ();
+                       }
+               }
+
+               class LocalFunctionsReferencedViaReflection
+               {
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--")]
+                       [ExpectedWarning ("IL3002", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestLocalFunctionWithRequires ()
+                       {
+                               LocalFunction ();
+
+                               [RequiresUnreferencedCode ("--TestLocalFunctionWithRequires--")]
+                               [RequiresAssemblyFiles ("--TestLocalFunctionWithRequires--")]
+                               [RequiresDynamicCode ("--TestLocalFunctionWithRequires--")]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       static void TestLocalFunctionWithRequiresOnlyAccessedViaReflection ()
+                       {
+                               [RequiresUnreferencedCode ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")]
+                               [RequiresAssemblyFiles ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")]
+                               [RequiresDynamicCode ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")]
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [ExpectedWarning ("IL2026", "LocalFunction")]
+                       [ExpectedWarning ("IL3002", "LocalFunction", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL3050", "LocalFunction", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                       static void TestLocalFunctionWithClosureWithRequires (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               [RequiresUnreferencedCode ("--TestLocalFunctionWithClosureWithRequires--")]
+                               [RequiresAssemblyFiles ("--TestLocalFunctionWithClosureWithRequires--")]
+                               [RequiresDynamicCode ("--TestLocalFunctionWithClosureWithRequires--")]
+                               void LocalFunction ()
+                               {
+                                       p++;
+                                       MethodWithRequires ();
+                               }
+                       }
+
+                       [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRequires--")]
+                       [RequiresAssemblyFiles ("--TestLocalFunctionInMethodWithRequires--")]
+                       [RequiresDynamicCode ("--TestLocalFunctionInMethodWithRequires--")]
+                       static void TestLocalFunctionInMethodWithRequires ()
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")]
+                       [RequiresAssemblyFiles ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")]
+                       [RequiresDynamicCode ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")]
+                       static void TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection ()
+                       {
+                               // This is unused, except for the reflection access. Don't warn about MethodWithRequires
+                               // because the reflection access will warn about accessing compiler-generated code.
+                               void LocalFunction () => MethodWithRequires ();
+                       }
+
+                       [RequiresUnreferencedCode ("--TestLocalFunctionWithClosureInMethodWithRequires--")]
+                       [RequiresAssemblyFiles ("--TestLocalFunctionWithClosureInMethodWithRequires--")]
+                       [RequiresDynamicCode ("--TestLocalFunctionWithClosureInMethodWithRequires--")]
+                       static void TestLocalFunctionWithClosureInMethodWithRequires (int p = 0)
+                       {
+                               LocalFunction ();
+
+                               void LocalFunction ()
+                               {
+                                       p++;
+                                       MethodWithRequires ();
+                               }
+                       }
+
+                       // Warnings for Reflection access to methods with Requires
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")]
+                       // The linker correctly emits warnings about reflection access to local functions with Requires
+                       // or which inherit Requires from the containing method. The analyzer doesn't bind to local functions
+                       // so does not warn here.
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       // BUG: https://github.com/dotnet/runtime/issues/68786
+                       // NativeAot doesn't associate Requires on method with the local functions it contains.
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       // Linker warns about reflection access to compiler-generated code
+                       // https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection),
+                               ProducedBy = ProducedBy.Trimmer)]
+                       static void TestAll ()
+                       {
+                               typeof (LocalFunctionsReferencedViaReflection).RequiresAll ();
+                       }
+
+                       // Warnings for Reflection access to methods with Requires
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")]
+                       // NonPublicMethods warns for local functions not emitted into display classes.
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       // BUG: https://github.com/dotnet/runtime/issues/68786
+                       // NativeAot doesn't associate Requires on method with the local functions it contains.
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       // Linker warns about reflection access to compiler-generated code
+                       // https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">",
+                               ProducedBy = ProducedBy.Trimmer)]
+                       static void TestNonPublicMethods ()
+                       {
+                               typeof (LocalFunctionsReferencedViaReflection).RequiresNonPublicMethods ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestAll ();
+                               TestNonPublicMethods ();
+                       }
+               }
+
+               class LambdasReferencedViaReflection
+               {
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "--TestLambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "--TestLambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestLambdaWithRequires ()
+                       {
+                               var lambda =
+                               [RequiresUnreferencedCode ("--TestLambdaWithRequires--")]
+                               [RequiresAssemblyFiles ("--TestLambdaWithRequires--")]
+                               [RequiresDynamicCode ("--TestLambdaWithRequires--")]
+                               () => MethodWithRequires ();
+
+                               lambda ();
+                       }
+
+                       // NativeAot is missing ldftn detection: https://github.com/dotnet/runtime/issues/68786
+                       [ExpectedWarning ("IL2026", "Lambda", ProducedBy = ProducedBy.Trimmer | ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3002", "Lambda", ProducedBy = ProducedBy.Analyzer)]
+                       [ExpectedWarning ("IL3050", "Lambda", ProducedBy = ProducedBy.Analyzer)]
+                       static void TestLambdaWithClosureWithRequires (int p = 0)
+                       {
+                               var lambda =
+                               [RequiresUnreferencedCode ("--TestLambdaWithClosureWithRequires--")]
+                               [RequiresAssemblyFiles ("--TestLambdaWithClosureWithRequires--")]
+                               [RequiresDynamicCode ("--TestLambdaWithClosureWithRequires--")]
+                               () => {
+                                       p++;
+                                       MethodWithRequires ();
+                               };
+
+                               lambda ();
+                       }
+
+                       [RequiresUnreferencedCode ("--TestLambdaInMethodWithRequires--")]
+                       [RequiresAssemblyFiles ("--TestLambdaInMethodWithRequires--")]
+                       [RequiresDynamicCode ("--TestLambdaInMethodWithRequires--")]
+                       static void TestLambdaInMethodWithRequires ()
+                       {
+                               var lambda = () => MethodWithRequires ();
+
+                               lambda ();
+                       }
+
+                       [RequiresUnreferencedCode ("--TestLambdaWithClosureInMethodWithRequires--")]
+                       [RequiresAssemblyFiles ("--TestLambdaWithClosureInMethodWithRequires--")]
+                       [RequiresDynamicCode ("--TestLambdaWithClosureInMethodWithRequires--")]
+                       static void TestLambdaWithClosureInMethodWithRequires (int p = 0)
+                       {
+                               var lambda = () => {
+                                       p++;
+                                       MethodWithRequires ();
+                               };
+
+                               lambda ();
+                       }
+
+                       // Warnings for Reflection access to methods with Requires
+                       [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithClosureInMethodWithRequires--")]
+                       // The linker correctly emits warnings about reflection access to lambdas with Requires
+                       // or which inherit Requires from the containing method. The analyzer doesn't bind to lambdas
+                       // so does not warn here.
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithClosureWithRequires--", ProducedBy = ProducedBy.Trimmer | ProducedBy.NativeAot)]
+                       // BUG: https://github.com/dotnet/runtime/issues/68786
+                       // NativeAot doesn't associate Requires on method with the lambdas it contains.
+                       [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithClosureInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)]
+                       static void TestAll ()
+                       {
+                               typeof (LambdasReferencedViaReflection).RequiresAll ();
+                       }
+
+                       // Warnings for Reflection access to methods with Requires
+                       [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRequires--")]
+                       [ExpectedWarning ("IL2026", "--TestLambdaWithClosureInMethodWithRequires--")]
+                       // NonPublicMethods doesn't warn for lambdas emitted into display class types.
+                       static void TestNonPublicMethods ()
+                       {
+                               typeof (LambdasReferencedViaReflection).RequiresNonPublicMethods ();
+                       }
+
+                       public static void Test ()
+                       {
+                               TestAll ();
+                               TestNonPublicMethods ();
+                       }
+               }
+
+               class ComplexCases
+               {
+                       public class AsyncBodyCallingMethodWithRequires
+                       {
+                               [RequiresUnreferencedCode ("")]
+                               [RequiresAssemblyFiles ("")]
+                               [RequiresDynamicCode ("")]
+                               static Task<object> MethodWithRequiresAsync (Type type)
+                               {
+                                       return Task.FromResult (new object ());
+                               }
+
+                               [RequiresUnreferencedCode ("ParentSuppression")]
+                               [RequiresAssemblyFiles ("ParentSuppression")]
+                               [RequiresDynamicCode ("ParentSuppression")]
+                               static async Task<object> AsyncMethodCallingRequires (Type type)
+                               {
+                                       using (var diposable = await GetDisposableAsync ()) {
+                                               return await MethodWithRequiresAsync (type);
+                                       }
+                               }
+
+                               [ExpectedWarning ("IL2026", "ParentSuppression")]
+                               [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               public static void Test ()
+                               {
+                                       AsyncMethodCallingRequires (typeof (object));
+                               }
+                       }
+
+                       public class GenericAsyncBodyCallingMethodWithRequires
+                       {
+                               [RequiresUnreferencedCode ("")]
+                               [RequiresAssemblyFiles ("")]
+                               [RequiresDynamicCode ("")]
+                               static ValueTask<TValue> MethodWithRequiresAsync<TValue> ()
+                               {
+                                       return ValueTask.FromResult (default (TValue));
+                               }
+
+                               [RequiresUnreferencedCode ("ParentSuppression")]
+                               [RequiresAssemblyFiles ("ParentSuppression")]
+                               [RequiresDynamicCode ("ParentSuppression")]
+                               static async Task<T> AsyncMethodCallingRequires<T> ()
+                               {
+                                       using (var disposable = await GetDisposableAsync ()) {
+                                               return await MethodWithRequiresAsync<T> ();
+                                       }
+                               }
+
+                               [ExpectedWarning ("IL2026", "ParentSuppression")]
+                               [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               public static void Test ()
+                               {
+                                       AsyncMethodCallingRequires<object> ();
+                               }
+                       }
+
+                       public class GenericAsyncEnumerableBodyCallingRequiresWithAnnotations
+                       {
+                               class RequiresOnCtor
+                               {
+                                       [RequiresUnreferencedCode ("")]
+                                       [RequiresAssemblyFiles ("")]
+                                       [RequiresDynamicCode ("")]
+                                       public RequiresOnCtor ()
+                                       {
+                                       }
+                               }
+
+                               [RequiresUnreferencedCode ("ParentSuppression")]
+                               [RequiresAssemblyFiles ("ParentSuppression")]
+                               [RequiresDynamicCode ("ParentSuppression")]
+                               static IAsyncEnumerable<TValue> AsyncEnumMethodCallingRequires<
+                                       [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] TValue> ()
+                               {
+                                       return CreateAsync ();
+
+                                       [RequiresUnreferencedCode ("")]
+                                       [RequiresAssemblyFiles]
+                                       [RequiresDynamicCode ("")]
+                                       static async IAsyncEnumerable<TValue> CreateAsync ()
+                                       {
+                                               await MethodAsync ();
+                                               new RequiresOnCtor ();
+                                               yield return default (TValue);
+                                       }
+                               }
+
+                               [ExpectedWarning ("IL2026", "ParentSuppression")]
+                               [ExpectedWarning ("IL3002", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               [ExpectedWarning ("IL3050", "ParentSuppression", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)]
+                               public static void Test ()
+                               {
+                                       AsyncEnumMethodCallingRequires<object> ();
+                               }
+                       }
+
+                       class Disposable : IDisposable { public void Dispose () { } }
+
+                       static Task<Disposable> GetDisposableAsync () { return Task.FromResult (new Disposable ()); }
+               }
+
+               static async Task<int> MethodAsync ()
+               {
+                       return await Task.FromResult (0);
+               }
+
+               [RequiresUnreferencedCode ("--MethodWithRequires--")]
+               [RequiresAssemblyFiles ("--MethodWithRequires--")]
+               [RequiresDynamicCode ("--MethodWithRequires--")]
+               static void MethodWithRequires ()
+               {
+               }
+
+               class TypeWithMethodWithRequires
+               {
+                       [RequiresUnreferencedCode ("--TypeWithMethodWithRequires.MethodWithRequires--")]
+                       [RequiresAssemblyFiles ("--TypeWithMethodWithRequires.MethodWithRequires--")]
+                       [RequiresDynamicCode ("--TypeWithMethodWithRequires.MethodWithRequires--")]
+                       static void MethodWithRequires ()
+                       {
+                       }
+               }
+
+               [RequiresUnreferencedCode ("Message from --MethodWithRequiresAndReturns--")]
+               [RequiresAssemblyFiles ("Message from --MethodWithRequiresAndReturns--")]
+               [RequiresDynamicCode ("Message from --MethodWithRequiresAndReturns--")]
+               public static string MethodWithRequiresAndReturns ()
+               {
+                       return "string";
+               }
+
+               static void MethodWithGenericWhichRequiresMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] T> ()
+               {
+               }
+
+               class TypeWithGenericWhichRequiresMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] T>
+               {
+               }
+
+               class TypeWithGenericWhichRequiresNonPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] T> { }
+
+               class TestType { }
+       }
+}
diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCodeRelease.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCodeRelease.cs
new file mode 100644 (file)
index 0000000..a5f79c8
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Threading.Tasks;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.RequiresCapability
+{
+       [ExpectedNoWarnings]
+       [SkipKeptItemsValidation]
+       [SetupCompileArgument ("/optimize+")]
+       [Define ("RELEASE")]
+       [SetupCompileArgument ("/main:Mono.Linker.Tests.Cases.RequiresCapability.RequiresInCompilerGeneratedCodeRelease")]
+       [SandboxDependency ("RequiresInCompilerGeneratedCode.cs")]
+       class RequiresInCompilerGeneratedCodeRelease
+       {
+               // This test just links the RequiresIncompilerGeneratedCode test in the Release configuration, to test
+               // with optimizations enabled for closures and state machine types.
+               // Sometimes the compiler optimizes away unused references to lambdas.
+               public static void Main ()
+               {
+                       RequiresInCompilerGeneratedCode.Main ();
+               }
+       }
+}
\ No newline at end of file
index e09966f22d45c16f4e51a7ba5f81d442fe7083c9..89cfe8201728114ffac2612198733e37895ffd9d 100644 (file)
@@ -102,8 +102,6 @@ namespace Mono.Linker.Tests.TestCasesRunner
                        List<MessageContainer> loggedMessages = logger.GetLoggedMessages ();
                        List<(IMemberDefinition, CustomAttribute)> expectedNoWarningsAttributes = new List<(IMemberDefinition, CustomAttribute)> ();
                        foreach (var attrProvider in GetAttributeProviders (original)) {
-                               if (attrProvider.ToString () is string mystring && mystring.Contains ("RequiresInCompilerGeneratedCode/SuppressInLambda"))
-                                       Debug.WriteLine ("Print");
                                foreach (var attr in attrProvider.CustomAttributes) {
                                        if (!IsProducedByNativeAOT (attr))
                                                continue;
@@ -159,10 +157,6 @@ namespace Mono.Linker.Tests.TestCasesRunner
                                                        bool expectedWarningFound = false;
 
                                                        foreach (var loggedMessage in loggedMessages) {
-                                                               if (loggedMessage.ToString ().Contains ("RequiresInCompilerGeneratedCode.SuppressInLambda")) {
-                                                                       Debug.WriteLine ("Print 2");
-                                                               }
-
                                                                if (loggedMessage.Category != MessageCategory.Warning || loggedMessage.Code != expectedWarningCodeNumber)
                                                                        continue;
 
@@ -213,21 +207,23 @@ namespace Mono.Linker.Tests.TestCasesRunner
                                                                                if (attrProvider is not IMemberDefinition expectedMember)
                                                                                        continue;
 
-                                                                               string actualName = methodDesc.OwningType.ToString ().Replace ("+", ".") + "." + methodDesc.Name;
-                                                                               if (actualName.Contains (expectedMember.DeclaringType.FullName.Replace ("/", ".")) &&
-                                                                                       actualName.Contains ("<" + expectedMember.Name + ">")) {
+                                                                               string? actualName = GetActualOriginDisplayName (methodDesc);
+                                                                               string expectedTypeName = ConvertSignatureToIlcFormat (GetExpectedOriginDisplayName (expectedMember.DeclaringType));
+                                                                               if (actualName?.Contains (expectedTypeName) == true &&
+                                                                                       actualName?.Contains ("<" + expectedMember.Name + ">") == true) {
                                                                                        expectedWarningFound = true;
                                                                                        loggedMessages.Remove (loggedMessage);
                                                                                        break;
                                                                                }
-                                                                               if (actualName.StartsWith (expectedMember.DeclaringType.FullName) &&
-                                                                                       actualName.Contains (".cctor") && (expectedMember is FieldDefinition || expectedMember is PropertyDefinition)) {
+                                                                               if (actualName?.StartsWith (expectedTypeName) == true &&
+                                                                                       actualName?.Contains (".cctor") == true &&
+                                                                                       (expectedMember is FieldDefinition || expectedMember is PropertyDefinition)) {
                                                                                        expectedWarningFound = true;
                                                                                        loggedMessages.Remove (loggedMessage);
                                                                                        break;
                                                                                }
                                                                                if (methodDesc.Name == ".ctor" &&
-                                                                               methodDesc.OwningType.ToString () == expectedMember.FullName) {
+                                                                                       methodDesc.OwningType.ToString () == expectedMember.FullName) {
                                                                                        expectedWarningFound = true;
                                                                                        loggedMessages.Remove (loggedMessage);
                                                                                        break;
@@ -359,6 +355,7 @@ namespace Mono.Linker.Tests.TestCasesRunner
                                provider switch {
                                        MethodDefinition method => method.GetDisplayName (),
                                        FieldDefinition field => field.GetDisplayName (),
+                                       TypeDefinition type => type.GetDisplayName (),
                                        IMemberDefinition member => member.FullName,
                                        AssemblyDefinition asm => asm.Name.Name,
                                        _ => throw new NotImplementedException ()
index 4617c3f6c9ec1f429adacadf8d6a23d337962299..6911201b8581a9e99d0f27673f27d14be6400b1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
 using System;