Skip to content

Dataflow analysis doesn't predict MakeGeneric use in local methods #127150

@MichalStrehovsky

Description

@MichalStrehovsky
MakeGeneric<Atom>();

static object MakeGeneric<T>() => Activator.CreateInstance(typeof(Gen<>).MakeGenericType(typeof(T)));

class Gen<T>;
struct Atom;

This produces no compile time warnings with native AOT (i.e. dataflow analysis around IntrinsicId.Type_MakeGenericType correctly analyzed the MakeGenericType call and placed a MakeGenericTypeSite into the dependency graph). However, the code doesn't work at runtime:

Unhandled exception. System.NotSupportedException: 'Gen`1[Atom]' is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility
   at System.Reflection.Runtime.TypeInfos.RuntimeTypeInfo.get_TypeHandle() + 0x94
   at Internal.Reflection.Core.Execution.ExecutionEnvironment.GetMethodInvoker(RuntimeTypeInfo, QMethodDefinition, RuntimeTypeInfo[], MemberInfo, Exception&) + 0x87
   at System.Reflection.Runtime.MethodInfos.NativeFormat.NativeFormatMethodCommon.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo, Exception&) + 0x49
   at System.Reflection.Runtime.MethodInfos.RuntimePlainConstructorInfo`1.get_UncachedMethodInvoker() + 0x45
   at System.ActivatorImplementation.CreateInstance(Type, Boolean) + 0xd0
   at Program.<Main>$(String[] args) + 0x9

This is because the the code in DataflowAnalyzedMethodNode.cs around SearchDynamicDependencies didn't kick in because the MakeGenericTypeSite was associated with the method that owns the local method (the implicity Main used for top-level statements in C#), not with the local method itself (the MakeGeneric method). This is because dataflow analysis considers compiler generated methods (such as local methods) parts of the declaring user method and we run dataflow analysis with the user method as the context. We likely need to do something so that the MakeGenericTypeSite becomes associated with the actual method in IL that will then be instantiated.

In this case we were supposed to see that MakeGeneric<Atom> was compiled and therefore we need Gen<Atom> but SearchDynamicDependencies didn't do it because we never got past the if (method.GetTypicalMethodDefinition() != analyzedMethod) check.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions