diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index adc808e43de5af..43c6df87a49f7b 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -469,6 +469,17 @@ internal Type[] GetInstantiationPublic() [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void Instantiate(QCallTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type); + internal RuntimeType Instantiate(RuntimeType inst) + { + IntPtr ptr = inst.TypeHandle.Value; + + RuntimeType? type = null; + RuntimeTypeHandle nativeHandle = GetNativeHandle(); + Instantiate(new QCallTypeHandle(ref nativeHandle), &ptr, 1, ObjectHandleOnStack.Create(ref type)); + GC.KeepAlive(inst); + return type!; + } + internal RuntimeType Instantiate(Type[]? inst) { // defensive copy to be sure array is not mutated from the outside during processing diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index f76df3efa49153..8ee18a5a6ff03a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -3238,15 +3238,29 @@ public override Type MakeGenericType(Type[] instantiation) if (instantiation == null) throw new ArgumentNullException(nameof(instantiation)); - RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length]; - if (!IsGenericTypeDefinition) - throw new InvalidOperationException( - SR.Format(SR.Arg_NotGenericTypeDefinition, this)); + throw new InvalidOperationException(SR.Format(SR.Arg_NotGenericTypeDefinition, this)); - if (GetGenericArguments().Length != instantiation.Length) + RuntimeType[] genericParameters = GetGenericArgumentsInternal(); + if (genericParameters.Length != instantiation.Length) throw new ArgumentException(SR.Argument_GenericArgsCount, nameof(instantiation)); + if (instantiation.Length == 1 && instantiation[0] is RuntimeType rt) + { + ThrowIfTypeNeverValidGenericArgument(rt); + try + { + return new RuntimeTypeHandle(this).Instantiate(rt); + } + catch (TypeLoadException e) + { + ValidateGenericArguments(this, new[] { rt }, e); + throw; + } + } + + RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length]; + bool foundSigType = false; bool foundNonRuntimeType = false; for (int i = 0; i < instantiation.Length; i++) @@ -3277,8 +3291,6 @@ public override Type MakeGenericType(Type[] instantiation) return System.Reflection.Emit.TypeBuilderInstantiation.MakeGenericType(this, (Type[])(instantiation.Clone())); } - RuntimeType[] genericParameters = GetGenericArgumentsInternal(); - SanityCheckGenericArguments(instantiationRuntimeType, genericParameters); Type ret;