diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index af1542186494d5..10bac5be472fe2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -624,6 +624,19 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact if (_type.IsInterface) dependencies.Add(factory.InterfaceUse(_type.GetTypeDefinition()), "Interface is used"); + // Array types that don't have generic interface methods can be created out of thin air + // at runtime by the type loader. We should never emit non-constructed forms of these MethodTables. + // There's similar logic for generic types, but that one is a conditional dependency conditioned + // on the presence of the type loader template for the canonical form of the type. + if (_type.IsArrayTypeWithoutGenericInterfaces()) + { + IEETypeNode maximallyConstructableType = factory.MaximallyConstructableType(_type); + if (maximallyConstructableType != this) + { + dependencies.Add(maximallyConstructableType, "Type is template-loadable"); + } + } + if (EmitVirtualSlots) { if (!_type.IsArrayTypeWithoutGenericInterfaces()) diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index acad3d3934194a..21889f70eab085 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -66,6 +66,7 @@ private static int Main() TestGenericMethodOnGenericType.Run(); TestIsValueTypeWithoutTypeHandle.Run(); TestMdArrayLoad.Run(); + TestMdArrayLoad2.Run(); TestByRefTypeLoad.Run(); TestGenericLdtoken.Run(); TestAbstractGenericLdtoken.Run(); @@ -2443,6 +2444,21 @@ public static void Run() } } + class TestMdArrayLoad2 + { + class Atom { } + + public static object MakeMdArray() => new T[1,1,1]; + + public static void Run() + { + var mi = typeof(TestMdArrayLoad2).GetMethod(nameof(MakeMdArray)).MakeGenericMethod(GetAtom()); + if (mi.Invoke(null, Array.Empty()) is not Atom[,,]) + throw new Exception(); + static Type GetAtom() => typeof(Atom); + } + } + class TestByRefTypeLoad { class Atom { }