private static bool VerifyGenericParamConstraint(InstantiationContext genericParamContext, GenericParameterDesc genericParam,
                                                         InstantiationContext instantiationParamContext, TypeDesc instantiationParam)
        {
            GenericConstraints constraints = genericParam.Constraints;

            // Check class constraint
            if ((constraints & GenericConstraints.ReferenceTypeConstraint) != 0)
            {
                if (!instantiationParam.IsGCPointer &&
                    !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.ReferenceTypeConstraint))
                {
                    return(false);
                }
            }

            // Check default constructor constraint
            if ((constraints & GenericConstraints.DefaultConstructorConstraint) != 0)
            {
                if (!instantiationParam.HasExplicitOrImplicitDefaultConstructor() &&
                    !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.DefaultConstructorConstraint))
                {
                    return(false);
                }
            }

            // Check struct constraint
            if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0)
            {
                if ((!instantiationParam.IsValueType || instantiationParam.IsNullable) &&
                    !CheckGenericSpecialConstraint(instantiationParam, GenericConstraints.NotNullableValueTypeConstraint))
                {
                    return(false);
                }
            }

            var instantiatedConstraints = new ArrayBuilder <TypeDesc>();

            GetInstantiatedConstraintsRecursive(instantiationParamContext, instantiationParam, ref instantiatedConstraints);

            foreach (var constraintType in genericParam.TypeConstraints)
            {
                var instantiatedType = constraintType.InstantiateSignature(genericParamContext.TypeInstantiation, genericParamContext.MethodInstantiation);
                if (CanCastConstraint(ref instantiatedConstraints, instantiatedType))
                {
                    continue;
                }

                if (!instantiationParam.CanCastTo(instantiatedType))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        private static bool VerifyGenericParamConstraint(Instantiation typeInstantiation, Instantiation methodInstantiation, GenericParameterDesc genericParam, TypeDesc instantiationParam)
        {
            GenericConstraints constraints = genericParam.Constraints;

            // Check class constraint
            if ((constraints & GenericConstraints.ReferenceTypeConstraint) != 0)
            {
                if (!instantiationParam.IsGCPointer)
                {
                    return(false);
                }
            }

            // Check default constructor constraint
            if ((constraints & GenericConstraints.DefaultConstructorConstraint) != 0)
            {
                if (!instantiationParam.HasExplicitOrImplicitDefaultConstructor())
                {
                    return(false);
                }
            }

            // Check struct constraint
            if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0)
            {
                if (!instantiationParam.IsValueType)
                {
                    return(false);
                }

                if (instantiationParam.IsNullable)
                {
                    return(false);
                }
            }

            foreach (var constraintType in genericParam.TypeConstraints)
            {
                var instantiatedType = constraintType.InstantiateSignature(typeInstantiation, methodInstantiation);
                if (!instantiationParam.CanCastTo(instantiatedType))
                {
                    return(false);
                }
            }

            return(true);
        }