return FALSE;
}
+BOOL TypeDesc::ContainsGenericVariables(BOOL methodOnly)
+{
+ if (IsGenericVariable())
+ {
+ if (!methodOnly)
+ return TRUE;
+
+ PTR_TypeVarTypeDesc pTyVar = dac_cast<PTR_TypeVarTypeDesc>(this);
+ return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef;
+ }
+
+ if (HasTypeParam())
+ {
+ return GetRootTypeParam().ContainsGenericVariables(methodOnly);
+ }
+
+ if (IsFnPtr())
+ {
+ return dac_cast<PTR_FnPtrTypeDesc>(this)->ContainsGenericVariables(methodOnly);
+ }
+
+ return FALSE;
+}
+
+
PTR_BaseDomain TypeDesc::GetDomain()
{
CONTRACTL
return FALSE;
} // FnPtrTypeDesc::IsSharedByGenericInstantiations
+BOOL
+FnPtrTypeDesc::ContainsGenericVariables(BOOL methodOnly)
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ for (DWORD i = 0; i <= m_NumArgs; i++)
+ {
+ if (m_RetAndArgTypes[i].ContainsGenericVariables(methodOnly))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+} // FnPtrTypeDesc::ContainsGenericVariables
+
#ifndef DACCESS_COMPILE
// Returns TRUE if all return and argument types are externally visible.
BOOL IsSharedByGenericInstantiations();
+ BOOL ContainsGenericVariables(BOOL methodOnly);
+
protected:
// See methodtable.h for details of the flags with the same name there
enum
BOOL IsSharedByGenericInstantiations();
+ BOOL ContainsGenericVariables(BOOL methodOnly);
+
#ifndef DACCESS_COMPILE
// Returns TRUE if all return and argument types are externally visible.
BOOL IsExternallyVisible() const;
STATIC_CONTRACT_NOTHROW;
SUPPORTS_DAC;
- if (HasTypeParam())
- {
- return GetTypeParam().ContainsGenericVariables(methodOnly);
- }
-
- if (IsGenericVariable())
- {
- if (!methodOnly)
- return TRUE;
-
- PTR_TypeVarTypeDesc pTyVar = dac_cast<PTR_TypeVarTypeDesc>(AsTypeDesc());
- return TypeFromToken(pTyVar->GetTypeOrMethodDef()) == mdtMethodDef;
- }
- else if (HasInstantiation())
- {
- if (GetMethodTable()->ContainsGenericVariables(methodOnly))
- return TRUE;
- }
-
- return FALSE;
+ if (IsTypeDesc())
+ return AsTypeDesc()->ContainsGenericVariables(methodOnly);
+ else
+ return AsMethodTable()->ContainsGenericVariables(methodOnly);
}
//@GENERICS:
Assert.Equal(typeof(Runtime.InteropServices.OutAttribute).Project(), parameters[1].GetRequiredCustomModifiers()[0]);
}
+ [Fact]
+ public static unsafe void GenericFunctionPointer()
+ {
+ Type t = typeof(FunctionPointerHolder).Project();
+
+ MethodInfo m1 = t.GetMethod(nameof(FunctionPointerHolder.GenericReturnValue), Bindings);
+ Type fcnPtr1 = m1.ReturnType;
+ Assert.True(fcnPtr1.IsFunctionPointer);
+ Assert.True(fcnPtr1.ContainsGenericParameters);
+
+ MethodInfo m2 = t.GetMethod(nameof(FunctionPointerHolder.GenericArgument), Bindings);
+ Type fcnPtr2 = m2.GetParameters()[1].ParameterType;
+ Assert.True(fcnPtr2.IsFunctionPointer);
+ Assert.True(fcnPtr2.ContainsGenericParameters);
+ }
+
[Theory]
[InlineData(nameof(FunctionPointerHolder.MethodReturnValue1),
"MethodReturnValue1()",
public delegate* unmanaged[Stdcall, MemberFunction]<string, ref bool*, MyClass, in MyStruct, double> SeveralArguments() => default;
public delegate*<in int, out int, void> RequiredModifiers() => default;
+ public delegate*<T> GenericReturnValue<T>() => default;
+ public bool GenericArgument<T>(int x, delegate*<T[], void> fptr) => default;
+
public class MyClass { }
public struct MyStruct { }
}
public sealed override bool IsGenericParameter => false;
public sealed override bool IsGenericTypeParameter => false;
public sealed override bool IsGenericMethodParameter => false;
- public sealed override bool ContainsGenericParameters => IsGenericTypeDefinition;
+
+ public sealed override bool ContainsGenericParameters
+ {
+ get
+ {
+ if (_returnType.ContainsGenericParameters)
+ return true;
+
+ foreach (Type parameterType in _parameterTypes)
+ {
+ if (parameterType.ContainsGenericParameters)
+ return true;
+ }
+
+ return false;
+ }
+ }
protected sealed override TypeCode GetTypeCodeImpl() => TypeCode.Object;
if (HasElementType)
return GetElementType().ContainsGenericParameters;
+ if (IsFunctionPointer)
+ {
+ if (GetFunctionPointerReturnType().ContainsGenericParameters)
+ return true;
+
+ foreach (Type arg in GetFunctionPointerParameterTypes())
+ if (arg.ContainsGenericParameters)
+ return true;
+ }
+
return false;
}
}