From 2a217af12b7c506e4afcf9a01035835d7db1678f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 21 Dec 2022 01:58:03 +0000 Subject: [PATCH 1/3] Reproduce failure in testcase --- .../DataFlow/CompilerGeneratedTypes.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs index f99a80b202292..c414bc252d128 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedTypes.cs @@ -32,6 +32,7 @@ public static void Main () AsyncCapture (); AsyncTypeMismatch (); AsyncInsideClosure (); + AsyncInsideClosureNonGeneric (); AsyncInsideClosureMismatch (); // Closures @@ -220,6 +221,22 @@ private static void AsyncInsideClosure () } } + private static void AsyncInsideClosureNonGeneric () + { + Outer (); + void Outer<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T1> () + { + int x = 0; + Inner ().Wait (); + async Task Inner () + { + await Task.Delay (0); + x++; + _ = typeof (T1).GetMethods (); + } + } + } + private static void AsyncInsideClosureMismatch () { Outer (); From 6c139662796e9dc521a90b0924286d4421403a06 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 21 Dec 2022 18:59:48 +0000 Subject: [PATCH 2/3] Map generic parameters inherited from declaring types --- .../Linker.Dataflow/CompilerGeneratedState.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs index cc7d205b9fb9d..04617793f7f3a 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/CompilerGeneratedState.cs @@ -283,7 +283,7 @@ referencedMethod.DeclaringType is var generatedType && // Now that we have instantiating methods fully filled out, walk the generated types and fill in the attribute // providers foreach (var generatedType in generatedTypeToTypeArgs.Keys) { - if (HasGenericParameters (generatedType)) { + if (generatedType.HasGenericParameters) { MapGeneratedTypeTypeParameters (generatedType, generatedTypeToTypeArgs, _context); // Finally, add resolved type arguments to the cache var info = generatedTypeToTypeArgs[generatedType]; @@ -298,19 +298,6 @@ referencedMethod.DeclaringType is var generatedType && _cachedTypeToCompilerGeneratedMembers.Add (type, compilerGeneratedCallees); return type; - /// - /// Check if the type itself is generic. The only difference is that - /// if the type is a nested type, the generic parameters from its - /// parent type don't count. - /// - static bool HasGenericParameters (TypeDefinition typeDef) - { - if (!typeDef.IsNested) - return typeDef.HasGenericParameters; - - return typeDef.GenericParameters.Count > typeDef.DeclaringType.GenericParameters.Count; - } - /// /// Attempts to reverse the process of the compiler's alpha renaming. So if the original code was /// something like this: From 21a172d59c7df55054e5b38ae212d84927a1d1f7 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 16 May 2023 21:44:20 +0000 Subject: [PATCH 3/3] Make same fix in ILCompiler --- .../Compiler/Dataflow/CompilerGeneratedState.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs index 359ccf70cfe78..cbfb822cc3c49 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs @@ -288,24 +288,11 @@ referencedMethod.OwningType is MetadataType generatedType && { Debug.Assert(generatedType == generatedType.GetTypeDefinition()); - if (HasGenericParameters(generatedType)) + if (generatedType.HasInstantiation) MapGeneratedTypeTypeParameters(generatedType); } } - /// - /// Check if the type itself is generic. The only difference is that - /// if the type is a nested type, the generic parameters from its - /// parent type don't count. - /// - static bool HasGenericParameters(MetadataType typeDef) - { - if (typeDef.ContainingType == null) - return typeDef.HasInstantiation; - - return typeDef.Instantiation.Length > typeDef.ContainingType.Instantiation.Length; - } - void MapGeneratedTypeTypeParameters(MetadataType generatedType) { Debug.Assert(CompilerGeneratedNames.IsGeneratedType(generatedType.Name));