<commit_before>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


using System.Diagnostics;

namespace Internal.TypeSystem
{
    public static class TypeSystemConstraintsHelpers
    {
        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;
        }

        public static bool CheckValidInstantiationArguments(this Instantiation instantiation)
        {
            foreach(var arg in instantiation)
            {
                if (arg.IsPointer || arg.IsByRef || arg.IsGenericParameter || arg.IsRuntimeDeterminedSubtype || arg.IsVoid)
                    return false;

                if (arg.HasInstantiation)
                {
                    if (!CheckValidInstantiationArguments(arg.Instantiation))
                        return false;
                }
            }
            return true;
        }

        public static bool CheckConstraints(this TypeDesc type)
        {
            TypeDesc uninstantiatedType = type.GetTypeDefinition();

            // Non-generic types always pass constraints check
            if (uninstantiatedType == type)
                return true;

            for (int i = 0; i < uninstantiatedType.Instantiation.Length; i++)
            {
                if (!VerifyGenericParamConstraint(type.Instantiation, default(Instantiation), (GenericParameterDesc)uninstantiatedType.Instantiation[i], type.Instantiation[i]))
                    return false;
            }<commit_msg>Remove the IsRuntimeDeterminedSubtype check from constraints checking (#3904)<commit_after>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


using System.Diagnostics;

namespace Internal.TypeSystem
{
    public static class TypeSystemConstraintsHelpers
    {
        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;
        }

        public static bool CheckValidInstantiationArguments(this Instantiation instantiation)
        {
            foreach(var arg in instantiation)
            {
                if (arg.IsPointer || arg.IsByRef || arg.IsGenericParameter || arg.IsVoid)
                    return false;

                if (arg.HasInstantiation)
                {
                    if (!CheckValidInstantiationArguments(arg.Instantiation))
                        return false;
                }
            }
            return true;
        }

        public static bool CheckConstraints(this TypeDesc type)
        {
            TypeDesc uninstantiatedType = type.GetTypeDefinition();

            // Non-generic types always pass constraints check
            if (uninstantiatedType == type)
                return true;

            for (int i = 0; i < uninstantiatedType.Instantiation.Length; i++)
            {
                if (!VerifyGenericParamConstraint(type.Instantiation, default(Instantiation), (GenericParameterDesc)uninstantiatedType.Instantiation[i], type.Instantiation[i]))
                    return false;
            }
{'fraction_non_alphanumeric': 0.06324900133155792, 'fraction_numerical': 0.0019973368841544607, 'mean_word_length': 1.8737446197991392, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3108467', 'n_tokens_mistral': 1372, 'n_tokens_neox': 1274, 'n_words': 344}