diff options
| author | Yong He <yonghe@outlook.com> | 2023-08-04 15:47:39 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-04 15:47:39 -0700 |
| commit | a2d90fb275962da84611160f8ddd74d934a68dbd (patch) | |
| tree | 066084537b9f4fe1f367de100ed6638a88a028c1 /source/slang/slang-check-decl.cpp | |
| parent | 17da4f0dec2b86ba3a4bdaf8a2ae112047d23623 (diff) | |
Redesign `DeclRef` and systematic `Val` deduplication (#3049)
* Redesign DeclRef + Deduplicate Val.
* Update project files
* Fix warning.
* Fix.
* Fix.
* Remove `Val::_equalsImplOverride`.
* Rmove `Val::_getHashCodeOverride`.
* Remove `semanticVisitor` param from `resolve`.
* Cleanups.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 564 |
1 files changed, 186 insertions, 378 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index b1dd2d533..b6a5d94ef 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -13,6 +13,8 @@ #include "slang-lookup.h" #include "slang-syntax.h" #include "slang-ast-synthesis.h" +#include "slang-ast-reflect.h" + #include <limits> namespace Slang @@ -201,12 +203,6 @@ namespace Slang void visitDecl(Decl*) {} void visitDeclGroup(DeclGroup*) {} - Val* resolveVal(Val* val); - Type* resolveType(Type* type) - { - return (Type*)resolveVal(type); - } - void visitTypeExp(TypeExp& exp) { exp.type = resolveType(exp.type); @@ -581,7 +577,7 @@ namespace Slang return getTypeForDeclRef(astBuilder, nullptr, nullptr, declRef, &typeResult, loc); } - DeclRef<ExtensionDecl> ApplyExtensionToType( + DeclRef<ExtensionDecl> applyExtensionToType( SemanticsVisitor* semantics, ExtensionDecl* extDecl, Type* type) @@ -589,118 +585,7 @@ namespace Slang if(!semantics) return DeclRef<ExtensionDecl>(); - return semantics->ApplyExtensionToType(extDecl, type); - } - - GenericSubstitution* createDefaultSubstitutionsForGeneric( - ASTBuilder* astBuilder, - SemanticsVisitor* semantics, - GenericDecl* genericDecl, - Substitutions* outerSubst) - { - GenericSubstitution* cachedResult = nullptr; - if (astBuilder->m_genericDefaultSubst.tryGetValue(genericDecl, cachedResult)) - { - if (cachedResult->getOuter() == outerSubst) - return cachedResult; - } - - List<Val*> args; - - for( auto mm : genericDecl->members ) - { - if( auto genericTypeParamDecl = as<GenericTypeParamDecl>(mm) ) - { - args.add(DeclRefType::create(astBuilder, astBuilder->getSpecializedDeclRef<Decl>(genericTypeParamDecl, outerSubst))); - } - else if( auto genericValueParamDecl = as<GenericValueParamDecl>(mm) ) - { - if (semantics) - ensureDecl(semantics, genericValueParamDecl, DeclCheckState::ReadyForLookup); - - args.add(astBuilder->getOrCreate<GenericParamIntVal>( - genericValueParamDecl->getType(), - astBuilder->getSpecializedDeclRef(genericValueParamDecl, outerSubst))); - } - } - - bool shouldCache = true; - - // create default substitution arguments for constraints - for (auto mm : genericDecl->members) - { - if (auto genericTypeConstraintDecl = as<GenericTypeConstraintDecl>(mm)) - { - if (semantics) - { - ensureDecl(semantics, genericTypeConstraintDecl, DeclCheckState::ReadyForReference); - } - auto constraintDeclRef = astBuilder->getSpecializedDeclRef<GenericTypeConstraintDecl>(genericTypeConstraintDecl, outerSubst); - auto witness = - astBuilder->getDeclaredSubtypeWitness( - getSub(astBuilder, constraintDeclRef), - getSup(astBuilder, constraintDeclRef), - astBuilder->getSpecializedDeclRef(genericTypeConstraintDecl, outerSubst)); - // TODO: this is an ugly hack to prevent crashing. - // In early stages of compilation witness->sub and witness->sup may not be checked yet. - // When semanticVisitor is present we have used that to ensure the type is checked. - // However due to how the code is written we cannot guarantee semanticVisitor is always available - // here, and if we can't get the checked sup/sub type this subst is incomplete and should not be - // cached. - if (!witness->sub) - shouldCache = false; - args.add(witness); - } - } - - GenericSubstitution* genericSubst = astBuilder->getOrCreateGenericSubstitution(outerSubst, genericDecl, args); - if (shouldCache) - astBuilder->m_genericDefaultSubst[genericDecl] = genericSubst; - return genericSubst; - } - - // Sometimes we need to refer to a declaration the way that it would be specialized - // inside the context where it is declared (e.g., with generic parameters filled in - // using their archetypes). - // - SubstitutionSet createDefaultSubstitutions( - ASTBuilder* astBuilder, - SemanticsVisitor* semantics, - Decl* decl, - SubstitutionSet outerSubstSet) - { - auto dd = decl->parentDecl; - if( auto genericDecl = as<GenericDecl>(dd) ) - { - // We don't want to specialize references to anything - // other than the "inner" declaration itself. - if(decl != genericDecl->inner) - return outerSubstSet; - - GenericSubstitution* genericSubst = createDefaultSubstitutionsForGeneric( - astBuilder, - semantics, - genericDecl, - outerSubstSet.substitutions); - - return SubstitutionSet(genericSubst); - } - - return outerSubstSet; - } - - SubstitutionSet createDefaultSubstitutions( - ASTBuilder* astBuilder, - SemanticsVisitor* semantics, - Decl* decl) - { - SubstitutionSet subst; - if( auto parentDecl = decl->parentDecl ) - { - subst = createDefaultSubstitutions(astBuilder, semantics, parentDecl); - } - subst = createDefaultSubstitutions(astBuilder, semantics, decl, subst); - return subst; + return semantics->applyExtensionToType(extDecl, type); } bool SemanticsVisitor::isDeclUsableAsStaticMember( @@ -1066,7 +951,7 @@ namespace Slang auto baseExprType = memberExpr->baseExpression->type.type; if (auto typeType = as<TypeType>(baseExprType)) { - if (diffThisType->equals(typeType->type)) + if (diffThisType->equals(typeType->getType())) { return; } @@ -1149,7 +1034,6 @@ namespace Slang { // A variable with an explicit type is simpler, for the // most part. - TypeExp typeExp = CheckUsableType(varDecl->type); varDecl->type = typeExp; if (varDecl->type.equals(m_astBuilder->getVoidType())) @@ -1256,7 +1140,7 @@ namespace Slang { if (auto basicType = as<BasicExpressionType>(varDecl->getType())) { - switch (basicType->baseType) + switch (basicType->getBaseType()) { case BaseType::Bool: case BaseType::Int8: @@ -1429,11 +1313,11 @@ namespace Slang { if (auto declRefType = as<DeclRefType>(sharedTypeExpr->base)) { - auto subst = createDefaultSubstitutions(m_astBuilder, this, declRefType->declRef.getDecl()); - auto newType = DeclRefType::create(m_astBuilder, m_astBuilder->getSpecializedDeclRef(declRefType->declRef.getDecl(), subst)); + auto newDeclRef = createDefaultSubstitutionsIfNeeded(m_astBuilder, this, declRefType->getDeclRef()); + auto newType = DeclRefType::create(m_astBuilder, newDeclRef); sharedTypeExpr->base.type = newType; if (auto typetype = as<TypeType>(typeExp.exp->type)) - typetype->type = newType; + typeExp.exp->type = m_astBuilder->getTypeType(newType); } } } @@ -1477,20 +1361,20 @@ namespace Slang } // If `This` is nested inside a generic, we need to form a complete declref type to the - // newly synthesized aggTypeDecl here. This can be done by obtaining ThisTypeSubstitution - // from requirementDeclRef to get the generic substitution for outer generic parameters, and + // newly synthesized aggTypeDecl here. This can be done by obtaining the this type witness + // from requirementDeclRef to get the generic arguments for the outer generic, and // apply it to the newly synthesized decl. SubstitutionSet substSet; - if (auto thisTypeSusbt = findThisTypeSubstitution( - requirementDeclRef.getSubst(), - as<InterfaceDecl>(requirementDeclRef.getParent(m_astBuilder)).getDecl())) + if (auto thisWitness = findThisTypeWitness( + SubstitutionSet(requirementDeclRef), + as<InterfaceDecl>(requirementDeclRef.getParent()).getDecl())) { - if (auto declRefType = as<DeclRefType>(thisTypeSusbt->witness->sub)) + if (auto declRefType = as<DeclRefType>(thisWitness->getSub())) { - substSet = declRefType->declRef.getSubst(); + substSet = SubstitutionSet(declRefType->getDeclRef()); } } - auto satisfyingType = DeclRefType::create(m_astBuilder, m_astBuilder->getSpecializedDeclRef(aggTypeDecl, substSet)); + auto satisfyingType = DeclRefType::create(m_astBuilder, m_astBuilder->getMemberDeclRef(substSet.declRef, aggTypeDecl)); // Helper function to add a `diffType` field into the synthesized type for the original // `member`. @@ -1513,8 +1397,7 @@ namespace Slang fieldLookupExpr->type.type = diffMemberType; auto baseTypeExpr = m_astBuilder->create<SharedTypeExpr>(); baseTypeExpr->base.type = differentialType; - auto baseTypeType = m_astBuilder->create<TypeType>(); - baseTypeType->type = differentialType; + auto baseTypeType = m_astBuilder->getOrCreate<TypeType>(differentialType); baseTypeExpr->type.type = baseTypeType; fieldLookupExpr->baseExpression = baseTypeExpr; fieldLookupExpr->declRef = makeDeclRef(diffField); @@ -1529,8 +1412,7 @@ namespace Slang fieldLookupExpr->type.type = diffMemberType; auto baseTypeExpr = m_astBuilder->create<SharedTypeExpr>(); baseTypeExpr->base.type = differentialType; - auto baseTypeType = m_astBuilder->create<TypeType>(); - baseTypeType->type = differentialType; + auto baseTypeType = m_astBuilder->getOrCreate<TypeType>(differentialType); baseTypeExpr->type.type = baseTypeType; fieldLookupExpr->baseExpression = baseTypeExpr; fieldLookupExpr->declRef = makeDeclRef(diffField); @@ -1545,7 +1427,7 @@ namespace Slang { if (auto declRefType = as<DeclRefType>(inheritanceDecl->base.type)) { - if (declRefType->declRef == m_astBuilder->getDifferentiableInterfaceDecl()) + if (declRefType->getDeclRef() == m_astBuilder->getDifferentiableInterfaceDecl()) { hasDifferentialConformance = true; break; @@ -1590,7 +1472,7 @@ namespace Slang if (auto baseDeclRefType = as<DeclRefType>(inheritance->base.type)) { // Skip interface super types. - if (baseDeclRefType->declRef.as<InterfaceDecl>()) + if (baseDeclRefType->getDeclRef().as<InterfaceDecl>()) continue; if (auto superDiffType = tryGetDifferentialType(m_astBuilder, baseDeclRefType)) { @@ -1618,6 +1500,9 @@ namespace Slang if (doesTypeSatisfyAssociatedTypeConstraintRequirement(satisfyingType, requirementDeclRef, witnessTable)) { witnessTable->add(requirementDeclRef.getDecl(), RequirementWitness(satisfyingType)); + + // Incrase the epoch so that future calls to Type::getCanonicalType will return the up-to-date folded types. + m_astBuilder->incrementEpoch(); return true; } @@ -1747,11 +1632,11 @@ namespace Slang auto baseType = as<DeclRefType>(inheritanceDecl->witnessTable->baseType); if (!baseType) return; - if (baseType->declRef.getDecl() != m_astBuilder->getDifferentiableInterfaceDecl().getDecl()) + if (baseType->getDeclRef().getDecl() != m_astBuilder->getDifferentiableInterfaceDecl().getDecl()) return; RequirementWitness witnessValue; auto requirementDecl = m_astBuilder->getSharedASTBuilder()->findBuiltinRequirementDecl(BuiltinRequirementKind::DifferentialType); - if (!inheritanceDecl->witnessTable->requirementDictionary.tryGetValue(requirementDecl, witnessValue)) + if (!inheritanceDecl->witnessTable->getRequirementDictionary().tryGetValue(requirementDecl, witnessValue)) return; // A type used as differential type must have itself as its own differential type. @@ -1763,7 +1648,7 @@ namespace Slang auto diffDiffType = tryGetDifferentialType(m_astBuilder, differentialType); if (!differentialType->equals(diffDiffType)) { - SourceLoc sourceLoc = differentialType->declRef.getDecl()->loc; + SourceLoc sourceLoc = differentialType->getDeclRef().getDecl()->loc; getSink()->diagnose(sourceLoc, Diagnostics::differentialTypeShouldServeAsItsOwnDifferentialType, differentialType); getSink()->diagnose(inheritanceDecl, Diagnostics::noteSeeUseOfDifferentialType, differentialType, inheritanceDecl->getSup()); } @@ -2287,7 +2172,7 @@ namespace Slang auto satisfyingVal = m_astBuilder->getOrCreate<GenericParamIntVal>( requiredValueParamDeclRef.getDecl()->getType(), satisfyingValueParamDeclRef); - satisfyingVal->declRef = satisfyingValueParamDeclRef; + satisfyingVal->getDeclRef() = satisfyingValueParamDeclRef; requiredSubstArgs.add(satisfyingVal); } @@ -2311,21 +2196,16 @@ namespace Slang } } - GenericSubstitution* requiredSubst = m_astBuilder->getOrCreateGenericSubstitution( - requiredGenericDeclRef.getSubst(), - requiredGenericDeclRef.getDecl(), - requiredSubstArgs); - // Now that we have computed a set of specialization arguments that will // specialize the generic requirement at the type parameters of the satisfying // generic, we can construct a reference to that declaration and re-run some // of the earlier checking logic with more type information usable. // - auto specializedRequiredGenericDeclRef = m_astBuilder->getSpecializedDeclRef<GenericDecl>(requiredGenericDeclRef.getDecl(), requiredSubst); - auto specializedRequiredMemberDeclRefs = getMembers(m_astBuilder, specializedRequiredGenericDeclRef); + auto specializedRequiredGenericInnerDeclRef = m_astBuilder->getGenericAppDeclRef( + requiredGenericDeclRef, requiredSubstArgs.getArrayView()); for (Index i = 0; i < memberCount; i++) { - auto requiredMemberDeclRef = specializedRequiredMemberDeclRefs[i]; + auto requiredMemberDeclRef = requiredMemberDeclRefs[i]; auto satisfyingMemberDeclRef = satisfyingMemberDeclRefs[i]; if(auto requiredTypeParamDeclRef = requiredMemberDeclRef.as<GenericTypeParamDecl>()) @@ -2365,13 +2245,16 @@ namespace Slang // In current code the sub type will always be one of the generic type parameters, // and the super-type will always be an interface, but there should be no // need to make use of those additional details here. - - auto requiredSubType = getSub(m_astBuilder, requiredConstraintDeclRef); + auto specializedRequiredConstraintDeclRef = m_astBuilder->getGenericAppDeclRef( + requiredGenericDeclRef, + requiredSubstArgs.getArrayView(), + requiredConstraintDeclRef.getDecl()).as<GenericTypeConstraintDecl>(); + auto requiredSubType = getSub(m_astBuilder, specializedRequiredConstraintDeclRef); auto satisfyingSubType = getSub(m_astBuilder, satisfyingConstraintDeclRef); if (!satisfyingSubType->equals(requiredSubType)) return false; - auto requiredSuperType = getSup(m_astBuilder, requiredConstraintDeclRef); + auto requiredSuperType = getSup(m_astBuilder, specializedRequiredConstraintDeclRef); auto satisfyingSuperType = getSup(m_astBuilder, satisfyingConstraintDeclRef); if (!satisfyingSuperType->equals(requiredSuperType)) return false; @@ -2400,8 +2283,8 @@ namespace Slang // declaration (whatever it is) for an exact match. // return doesMemberSatisfyRequirement( - m_astBuilder->getSpecializedDeclRef<Decl>(satisfyingGenericDeclRef.getDecl()->inner, satisfyingGenericDeclRef.getSubst()), - m_astBuilder->getSpecializedDeclRef<Decl>(requiredGenericDeclRef.getDecl()->inner, requiredSubst), + m_astBuilder->getMemberDeclRef(satisfyingGenericDeclRef, getInner(satisfyingGenericDeclRef)), + specializedRequiredGenericInnerDeclRef, witnessTable); } @@ -2444,7 +2327,7 @@ namespace Slang { // If we are seeing a placeholder that awaits synthesis, return false now to trigger // auto synthesis. - if (declRefType->declRef.getDecl()->hasModifier<ToBeSynthesizedModifier>()) + if (declRefType->getDeclRef().getDecl()->hasModifier<ToBeSynthesizedModifier>()) return false; } // We need to confirm that the chosen type `satisfyingType`, @@ -2466,7 +2349,7 @@ namespace Slang // type can indeed satisfy the interface requirement. witnessTable->add( requiredAssociatedTypeDeclRef.getDecl(), - RequirementWitness(satisfyingType)); + RequirementWitness(satisfyingType->getCanonicalType())); } return conformance; @@ -2563,7 +2446,7 @@ namespace Slang // check if the specified type satisfies the constraints defined by the associated type if (auto requiredTypeDeclRef = requiredMemberDeclRef.as<AssocTypeDecl>()) { - ensureDecl(typedefDeclRef, DeclCheckState::CanUseAsType); + ensureDecl(typedefDeclRef, DeclCheckState::ReadyForLookup); auto satisfyingType = getNamedType(m_astBuilder, typedefDeclRef); return doesTypeSatisfyAssociatedTypeRequirement(satisfyingType, requiredTypeDeclRef, witnessTable); @@ -2648,9 +2531,6 @@ namespace Slang { if (auto constraintDecl = as<GenericTypeConstraintDecl>(member)) { - getASTBuilder()->getSpecializedDeclRef( - constraintDecl, requiredMemberDeclRef.getSubst()); - auto synConstraintDecl = m_astBuilder->create<GenericTypeConstraintDecl>(); synConstraintDecl->nameAndLoc = constraintDecl->getNameAndLoc(); synConstraintDecl->parentDecl = synGenericDecl; @@ -2658,7 +2538,7 @@ namespace Slang // For constraints of type T : Interface, where T is a simple type parameter, // find the declaration of T // - if (auto typeParamDecl = as<DeclRefType>(constraintDecl->sub.type)->declRef.as<GenericTypeParamDecl>().getDecl()) + if (auto typeParamDecl = as<DeclRefType>(constraintDecl->sub.type)->getDeclRef().as<GenericTypeParamDecl>().getDecl()) { auto synTypeParamDecl = mapOrigToSynTypeParams[typeParamDecl]; @@ -2680,37 +2560,19 @@ namespace Slang } } - // Get outer substitutions. (This inner-most substition - // must be a ThisTypeSubstition) - // - Substitutions* outer = nullptr; - if (auto thisTypeSubst = findThisTypeSubstitution( - requiredMemberDeclRef.getSubst(), - as<InterfaceDecl>(requiredMemberDeclRef.getParent(m_astBuilder)).getDecl())) - { - outer = thisTypeSubst; - } - // Override generic pointer to point to the original generic container. // This will create a substitution of the synthesized parameters for the // original parameters. - // - GenericSubstitution* requiredFuncSubsts = createDefaultSubstitutionsForGeneric(m_astBuilder, this, requiredMemberDeclRef.getDecl(), outer); - DeclRef<Decl> requiredFuncDeclRef = m_astBuilder->getSpecializedDeclRef(requiredMemberDeclRef.getDecl()->inner, requiredFuncSubsts); - - GenericSubstitution* substSynParamsForOrigGeneric = m_astBuilder->getOrCreateGenericSubstitution( - outer, - requiredMemberDeclRef.getDecl(), - createDefaultSubstitutionsForGeneric(m_astBuilder, this, synGenericDecl, nullptr)->getArgs()); - - // Substitute parameters of the synthesized generic for the parameters of the original generic. - requiredFuncDeclRef = substituteDeclRef(substSynParamsForOrigGeneric, m_astBuilder, requiredFuncDeclRef); + // + auto defaultArgs = getDefaultSubstitutionArgs(m_astBuilder, this, synGenericDecl); + DeclRef<FuncDecl> requiredFuncDeclRef = m_astBuilder->getGenericAppDeclRef( + requiredMemberDeclRef, defaultArgs.getArrayView()).as<FuncDecl>(); - SLANG_ASSERT(requiredFuncDeclRef.as<FuncDecl>()); + SLANG_ASSERT(requiredFuncDeclRef); synGenericDecl->inner = synthesizeMethodSignatureForRequirementWitness( context, - requiredFuncDeclRef.as<FuncDecl>(), + requiredFuncDeclRef, synArgs, synThis); synGenericDecl->inner->parentDecl = synGenericDecl; @@ -2860,14 +2722,12 @@ namespace Slang { if (auto fwdReq = as<ForwardDerivativeRequirementDecl>(reqRefDecl->referencedDecl)) { - ForwardDifferentiateVal* val = m_astBuilder->create<ForwardDifferentiateVal>(); - val->func = satisfyingMemberDeclRef; + ForwardDifferentiateVal* val = m_astBuilder->getOrCreate<ForwardDifferentiateVal>(satisfyingMemberDeclRef); witnessTable->add(fwdReq, RequirementWitness(val)); } else if (auto bwdReq = as<BackwardDerivativeRequirementDecl>(reqRefDecl->referencedDecl)) { - DifferentiateVal* val = m_astBuilder->create<BackwardDifferentiateVal>(); - val->func = satisfyingMemberDeclRef; + DifferentiateVal* val = m_astBuilder->getOrCreate<BackwardDifferentiateVal>(satisfyingMemberDeclRef); witnessTable->add(bwdReq, RequirementWitness(val)); } } @@ -3127,7 +2987,7 @@ namespace Slang // or uses, an associated type or `This`. // // Ideally we should be looking up the type using a `DeclRef` that - // refers to the interface requirement using a `ThisTypeSubstitution` + // refers to the interface requirement using a `LookupDeclRef` // that refers to the satisfying type declaration, and requirement // checking for non-associated-type requirements should be done *after* // requirement checking for associated-type requirements. @@ -3577,7 +3437,7 @@ namespace Slang // First we need to make sure the associated `Differential` type requirement is satisfied. bool hasDifferentialAssocType = false; - for (auto existingEntry : witnessTable->requirementDictionary) + for (auto& existingEntry : witnessTable->getRequirementDictionary()) { if (auto builtinReqAttr = existingEntry.key->findModifier<BuiltinRequirementModifier>()) { @@ -3726,20 +3586,33 @@ namespace Slang // If `This` is nested inside a generic, we need to form a complete declref type to the // newly synthesized method here in order to fill into the witness table. - // This can be done by obtaining ThisTypeSubstitution from requirementDeclRef to get the + // This can be done by obtaining the ThisType witness from requirementDeclRef to get the // generic substitution for outer generic parameters, and apply it here. SubstitutionSet substSet; - if (auto thisTypeSubst = findThisTypeSubstitution( - requirementDeclRef.getSubst(), + if (auto thisTypeWitness = findThisTypeWitness( + SubstitutionSet(requirementDeclRef), as<InterfaceDecl>(requirementDeclRef.getDecl()->parentDecl))) { - if (auto declRefType = as<DeclRefType>(thisTypeSubst->witness->sub)) + if (auto declRefType = as<DeclRefType>(thisTypeWitness->getSub())) { - substSet = declRefType->declRef.getSubst(); + substSet = SubstitutionSet(declRefType->getDeclRef()); } } + if (auto outerGeneric = GetOuterGeneric(context->parentDecl)) + { + // If the context->parentDecl is not the same as ThisType represented by genApp, then it must be an extension + // to ThisType. In this case, we need to form a new GenericAppDeclRef to specailizethe outer parent extension + // decl. Note that the extension might be a partial extension with some generic arguments missing, and + // we can't support that case right now. For now we can just assume the extension will have the same set + // of generic parameters as the target type. + auto defaultArgs = getDefaultSubstitutionArgs(m_astBuilder, this, outerGeneric); + auto specializedParent = m_astBuilder->getGenericAppDeclRef(makeDeclRef(outerGeneric), defaultArgs.getArrayView()); + auto specializedFunc = m_astBuilder->getMemberDeclRef(specializedParent, synFunc); + witnessTable->add(requirementDeclRef.getDecl(), RequirementWitness(specializedFunc)); + return true; + } - witnessTable->add(requirementDeclRef.getDecl(), RequirementWitness(m_astBuilder->getSpecializedDeclRef<Decl>(synFunc, substSet))); + witnessTable->add(requirementDeclRef.getDecl(), RequirementWitness(m_astBuilder->getDirectDeclRef(synFunc))); return true; } @@ -3767,11 +3640,16 @@ namespace Slang // witness in the table for the requirement, so // that we can bail out early. // - if(witnessTable->requirementDictionary.containsKey(requiredMemberDeclRef.getDecl())) + if(witnessTable->getRequirementDictionary().containsKey(requiredMemberDeclRef.getDecl())) { return true; } + // The ThisType requirement is always satisfied. + if (as<ThisTypeDecl>(requiredMemberDeclRef.getDecl())) + { + return true; + } // An important exception to the above is that an // inheritance declaration in the interface is not going @@ -3987,17 +3865,13 @@ namespace Slang ensureDecl(superInterfaceDeclRef, DeclCheckState::CanReadInterfaceRequirements); // When comparing things like signatures, we need to do so in the context - // of a this-type substitution that aligns the signatures in the interface + // of a LookupDeclRef that aligns the signatures in the interface // with those in the concrete type. For example, we need to treat any uses // of `This` in the interface as equivalent to the concrete type for the // purpose of signature matching (and similarly for associated types). // - ThisTypeSubstitution* thisTypeSubst = m_astBuilder->getOrCreateThisTypeSubstitution( - superInterfaceDeclRef.getDecl(), - subTypeConformsToSuperInterfaceWitness, - superInterfaceDeclRef.getSubst()); - - auto specializedSuperInterfaceDeclRef = m_astBuilder->getSpecializedDeclRef<InterfaceDecl>(superInterfaceDeclRef.getDecl(), thisTypeSubst); + auto thisTypeDeclRef = m_astBuilder->getLookupDeclRef( + subTypeConformsToSuperInterfaceWitness, superInterfaceDeclRef.getDecl()->getThisTypeDecl()); bool result = true; @@ -4029,35 +3903,36 @@ namespace Slang // constraints and solve for those type variables as part of the // conformance-checking process. // - for(auto requiredMemberDeclRef : getMembers(m_astBuilder, specializedSuperInterfaceDeclRef)) + for(auto requiredMemberDecl : getMembers(m_astBuilder, superInterfaceDeclRef)) { - if(!isAssociatedTypeDecl(requiredMemberDeclRef.getDecl())) + if(!isAssociatedTypeDecl(requiredMemberDecl.getDecl())) continue; - + auto requiredMemberDeclRef = m_astBuilder->getLookupDeclRef(subTypeConformsToSuperInterfaceWitness, requiredMemberDecl.getDecl()); auto requirementSatisfied = findWitnessForInterfaceRequirement( context, subType, superInterfaceType, inheritanceDecl, - specializedSuperInterfaceDeclRef, + thisTypeDeclRef, requiredMemberDeclRef, witnessTable, subTypeConformsToSuperInterfaceWitness); result = result && requirementSatisfied; } - for(auto requiredMemberDeclRef : getMembers(m_astBuilder, specializedSuperInterfaceDeclRef)) + for(auto requiredMemberDecl : getMembers(m_astBuilder, superInterfaceDeclRef)) { - if(isAssociatedTypeDecl(requiredMemberDeclRef.getDecl())) + if(isAssociatedTypeDecl(requiredMemberDecl.getDecl())) continue; - if (requiredMemberDeclRef.as<DerivativeRequirementDecl>()) + if (requiredMemberDecl.as<DerivativeRequirementDecl>()) continue; + auto requiredMemberDeclRef = m_astBuilder->getLookupDeclRef(subTypeConformsToSuperInterfaceWitness, requiredMemberDecl.getDecl()); auto requirementSatisfied = findWitnessForInterfaceRequirement( context, subType, superInterfaceType, inheritanceDecl, - specializedSuperInterfaceDeclRef, + thisTypeDeclRef, requiredMemberDeclRef, witnessTable, subTypeConformsToSuperInterfaceWitness); @@ -4089,25 +3964,27 @@ namespace Slang // the time we are compiling and handle those, and punt on the larger issue // for a bit longer. // - for(auto candidateExt : getCandidateExtensions(specializedSuperInterfaceDeclRef, this)) + for(auto candidateExt : getCandidateExtensions(superInterfaceDeclRef, this)) { // We need to apply the extension to the interface type that our // concrete type is inheriting from. // - Type* targetType = DeclRefType::create(m_astBuilder, specializedSuperInterfaceDeclRef); - auto extDeclRef = ApplyExtensionToType(candidateExt, targetType); - if(!extDeclRef) + Type* targetType = DeclRefType::create(m_astBuilder, thisTypeDeclRef); + auto parentDeclRef = applyExtensionToType(candidateExt, targetType); + if(!parentDeclRef) continue; // Only inheritance clauses from the extension matter right now. - for(auto requiredInheritanceDeclRef : getMembersOfType<InheritanceDecl>(m_astBuilder, extDeclRef)) + for(auto requiredInheritanceDecl : getMembersOfType<InheritanceDecl>(m_astBuilder, candidateExt)) { + auto requiredInheritanceDeclRef = m_astBuilder->getLookupDeclRef( + subTypeConformsToSuperInterfaceWitness, requiredInheritanceDecl.getDecl()); auto requirementSatisfied = findWitnessForInterfaceRequirement( context, subType, superInterfaceType, inheritanceDecl, - specializedSuperInterfaceDeclRef, + thisTypeDeclRef, requiredInheritanceDeclRef, witnessTable, subTypeConformsToSuperInterfaceWitness); @@ -4131,7 +4008,7 @@ namespace Slang { if (auto supereclRefType = as<DeclRefType>(superType)) { - auto superTypeDeclRef = supereclRefType->declRef; + auto superTypeDeclRef = supereclRefType->getDeclRef(); if (auto superInterfaceDeclRef = superTypeDeclRef.as<InterfaceDecl>()) { // The type is stating that it conforms to an interface. @@ -4172,11 +4049,11 @@ namespace Slang if( auto declRefType = as<DeclRefType>(subType) ) { - auto declRef = declRefType->declRef; + auto declRef = declRefType->getDeclRef(); if (auto superDeclRefType = as<DeclRefType>(superType)) { - auto superTypeDecl = superDeclRefType->declRef.getDecl(); + auto superTypeDecl = superDeclRefType->getDeclRef().getDecl(); if (superTypeDecl->findModifier<ComInterfaceAttribute>()) { // A struct cannot implement a COM Interface. @@ -4228,10 +4105,7 @@ namespace Slang // Look at the type being inherited from, and validate // appropriately. - DeclaredSubtypeWitness* subIsSuperWitness = m_astBuilder->create<DeclaredSubtypeWitness>(); - subIsSuperWitness->declRef = makeDeclRef(inheritanceDecl); - subIsSuperWitness->sub = subType; - subIsSuperWitness->sup = superType; + DeclaredSubtypeWitness* subIsSuperWitness = m_astBuilder->getDeclaredSubtypeWitness(subType, superType, makeDeclRef(inheritanceDecl)); ConformanceCheckingContext context; context.conformingType = subType; @@ -4333,7 +4207,7 @@ namespace Slang { return; } - auto baseDecl = baseDeclRefType->declRef.getDecl(); + auto baseDecl = baseDeclRefType->getDeclRef().getDecl(); // Using the parent/child hierarchy baked into `Decl`s we // can find the modules that contain both the `decl` doing @@ -4415,7 +4289,7 @@ namespace Slang continue; } - auto baseDeclRef = baseDeclRefType->declRef; + auto baseDeclRef = baseDeclRefType->getDeclRef(); auto baseInterfaceDeclRef = baseDeclRef.as<InterfaceDecl>(); if( !baseInterfaceDeclRef ) { @@ -4476,7 +4350,7 @@ namespace Slang continue; } - auto baseDeclRef = baseDeclRefType->declRef; + auto baseDeclRef = baseDeclRefType->getDeclRef(); if( auto baseInterfaceDeclRef = baseDeclRef.as<InterfaceDecl>() ) { } @@ -4545,7 +4419,7 @@ namespace Slang continue; } - auto baseDeclRef = baseDeclRefType->declRef; + auto baseDeclRef = baseDeclRefType->getDeclRef(); if (auto baseInterfaceDeclRef = baseDeclRef.as<InterfaceDecl>()) { } @@ -4594,8 +4468,8 @@ namespace Slang auto basicType = as<BasicExpressionType>(type); if(!basicType) return false; - - return isIntegerBaseType(basicType->baseType) || basicType->baseType == BaseType::Bool; + auto baseType = basicType->getBaseType(); + return isIntegerBaseType(baseType) || baseType == BaseType::Bool; } bool SemanticsVisitor::isIntValueInRangeOfType(IntegerLiteralValue value, Type* type) @@ -4604,7 +4478,7 @@ namespace Slang if (!basicType) return false; - switch (basicType->baseType) + switch (basicType->getBaseType()) { case BaseType::UInt8: return (value >= 0 && value <= std::numeric_limits<uint8_t>::max()) || (value == -1); @@ -4686,7 +4560,7 @@ namespace Slang continue; } - auto baseDeclRef = baseDeclRefType->declRef; + auto baseDeclRef = baseDeclRefType->getDeclRef(); if( auto baseInterfaceDeclRef = baseDeclRef.as<InterfaceDecl>() ) { _validateCrossModuleInheritance(decl, inheritanceDecl); @@ -4790,7 +4664,7 @@ namespace Slang Decl* tagAssociatedTypeDecl = nullptr; if(auto enumTypeTypeDeclRefType = dynamicCast<DeclRefType>(enumTypeType)) { - if(auto enumTypeTypeInterfaceDecl = as<InterfaceDecl>(enumTypeTypeDeclRefType->declRef.getDecl())) + if(auto enumTypeTypeInterfaceDecl = as<InterfaceDecl>(enumTypeTypeDeclRefType->getDeclRef().getDecl())) { for(auto memberDecl : enumTypeTypeInterfaceDecl->members) { @@ -4861,7 +4735,7 @@ namespace Slang { if(auto constIntVal = as<ConstantIntVal>(explicitTagVal)) { - defaultTag = constIntVal->value; + defaultTag = constIntVal->getValue(); } else { @@ -5015,7 +4889,7 @@ namespace Slang bool SemanticsVisitor::doGenericSignaturesMatch( GenericDecl* left, GenericDecl* right, - GenericSubstitution** outSubstRightToLeft) + DeclRef<Decl>* outSpecializedRightInner) { // Our first goal here is to determine if `left` and // `right` have equivalent lists of explicit @@ -5133,9 +5007,9 @@ namespace Slang // `foo2<T>` so that its constraint, after specialization, // looks like `T : IFoo`. // - auto& substRightToLeft = *outSubstRightToLeft; - List<Val*> leftArgs = getDefaultSubstitutionArgs(left); - substRightToLeft = getASTBuilder()->getOrCreateGenericSubstitution(nullptr, right, leftArgs); + auto& substInnerRightToLeft = *outSpecializedRightInner; + List<Val*> leftArgs = getDefaultSubstitutionArgs(m_astBuilder, this, left); + substInnerRightToLeft = m_astBuilder->getGenericAppDeclRef(makeDeclRef(right), leftArgs.getArrayView()); // We should now be able to enumerate the constraints // on `right` in a way that uses the same type parameters @@ -5207,7 +5081,9 @@ namespace Slang // arguments into account. // GenericTypeConstraintDecl* leftConstraint = leftConstraints[cc]; - DeclRef<GenericTypeConstraintDecl> rightConstraint = m_astBuilder->getSpecializedDeclRef(rightConstraints[cc], substRightToLeft); + auto unspecializedRightConstarintDeclRef = createDefaultSubstitutionsIfNeeded(m_astBuilder, this, makeDeclRef(rightConstraints[cc])); + DeclRef<GenericTypeConstraintDecl> rightConstraint = substInnerRightToLeft.substitute( + m_astBuilder, unspecializedRightConstarintDeclRef).as<GenericTypeConstraintDecl>(); // For now, every constraint has the form `sub : sup` // to indicate that `sub` must be a subtype of `sup`. @@ -5277,44 +5153,59 @@ namespace Slang return true; } - List<Val*> SemanticsVisitor::getDefaultSubstitutionArgs(GenericDecl* genericDecl) + List<Val*> getDefaultSubstitutionArgs(ASTBuilder* astBuilder, SemanticsVisitor* semantics, GenericDecl* genericDecl) { List<Val*> args; - for (auto dd : genericDecl->members) - { - if (dd == genericDecl->inner) - continue; + if (astBuilder->m_cachedGenericDefaultArgs.tryGetValue(genericDecl, args)) + return args; - if (auto typeParam = as<GenericTypeParamDecl>(dd)) + for (auto mm : genericDecl->members) + { + if (auto genericTypeParamDecl = as<GenericTypeParamDecl>(mm)) { - auto type = DeclRefType::create(m_astBuilder, makeDeclRef(typeParam)); - args.add(type); + args.add(DeclRefType::create(astBuilder, astBuilder->getDirectDeclRef(genericTypeParamDecl))); } - else if (auto valueParam = as<GenericValueParamDecl>(dd)) + else if (auto genericValueParamDecl = as<GenericValueParamDecl>(mm)) { - auto val = m_astBuilder->getOrCreate<GenericParamIntVal>( - valueParam->getType(), - DeclRef<VarDeclBase>(valueParam)); - args.add(val); + if (semantics) + semantics->ensureDecl(genericValueParamDecl, DeclCheckState::ReadyForLookup); + + args.add(astBuilder->getOrCreate<GenericParamIntVal>( + genericValueParamDecl->getType(), + astBuilder->getDirectDeclRef(genericValueParamDecl))); } } - // Add defaults for constraint parameters. - for (auto dd : genericDecl->members) + bool shouldCache = true; + + // create default substitution arguments for constraints + for (auto mm : genericDecl->members) { - if (auto constraintDecl = as<GenericTypeConstraintDecl>(dd)) + if (auto genericTypeConstraintDecl = as<GenericTypeConstraintDecl>(mm)) { - // Convert the constraint to an appropriate witness. - auto witness = tryGetSubtypeWitness(constraintDecl->sub, constraintDecl->sup); - - // Must be non-null since we know there's a constraint. If null, something is - // very wrong. - // - SLANG_ASSERT(witness); - + if (semantics) + semantics->ensureDecl(genericTypeConstraintDecl, DeclCheckState::ReadyForReference); + auto constraintDeclRef = astBuilder->getDirectDeclRef<GenericTypeConstraintDecl>(genericTypeConstraintDecl); + auto witness = + astBuilder->getDeclaredSubtypeWitness( + getSub(astBuilder, constraintDeclRef), + getSup(astBuilder, constraintDeclRef), + constraintDeclRef); + // TODO: this is an ugly hack to prevent crashing. + // In early stages of compilation witness->sub and witness->sup may not be checked yet. + // When semanticVisitor is present we have used that to ensure the type is checked. + // However due to how the code is written we cannot guarantee semanticVisitor is always available + // here, and if we can't get the checked sup/sub type this subst is incomplete and should not be + // cached. + if (!witness->getSub()) + shouldCache = false; args.add(witness); } } + + if (shouldCache) + astBuilder->m_cachedGenericDefaultArgs[genericDecl] = args; + return args; } @@ -5442,11 +5333,11 @@ namespace Slang // Then we will compare the parameter types of `foo2` // against the specialization `foo1<U>`. // - GenericSubstitution* subst = nullptr; - if(!doGenericSignaturesMatch(newGenericDecl, oldGenericDecl, &subst)) + DeclRef<Decl> specializedOldDeclInner; + if(!doGenericSignaturesMatch(newGenericDecl, oldGenericDecl, &specializedOldDeclInner)) return SLANG_OK; - oldDeclRef = getASTBuilder()->getSpecializedDeclRef(oldDecl, subst); + oldDeclRef = specializedOldDeclInner.as<FuncDecl>(); } // If the parameter signatures don't match, then don't worry @@ -5869,7 +5760,7 @@ namespace Slang auto reqDecl = m_astBuilder->create<ForwardDerivativeRequirementDecl>(); reqDecl->originalRequirementDecl = decl; cloneModifiers(reqDecl, decl); - auto declRef = m_astBuilder->getSpecializedDeclRef<CallableDecl>(decl, createDefaultSubstitutions(m_astBuilder, this, decl)); + auto declRef = createDefaultSubstitutionsIfNeeded(m_astBuilder, this, makeDeclRef(decl)).as<CallableDecl>(); auto diffFuncType = getForwardDiffFuncType(getFuncType(m_astBuilder, declRef)); setFuncTypeIntoRequirementDecl(reqDecl, as<FuncType>(diffFuncType)); interfaceDecl->members.add(reqDecl); @@ -5884,7 +5775,7 @@ namespace Slang if (decl->hasModifier<BackwardDifferentiableAttribute>()) { // Requirement for backward derivative. - auto declRef = m_astBuilder->getSpecializedDeclRef<CallableDecl>(decl, createDefaultSubstitutions(m_astBuilder, this, decl)); + auto declRef = createDefaultSubstitutionsIfNeeded(m_astBuilder, this, makeDeclRef(decl)).as<CallableDecl>(); auto originalFuncType = getFuncType(m_astBuilder, declRef); auto diffFuncType = as<FuncType>(getBackwardDiffFuncType(originalFuncType)); { @@ -5953,7 +5844,7 @@ namespace Slang IntegerLiteralValue SemanticsVisitor::GetMinBound(IntVal* val) { if (auto constantVal = as<ConstantIntVal>(val)) - return constantVal->value; + return constantVal->getValue(); // TODO(tfoley): Need to track intervals so that this isn't just a lie... return 1; @@ -6024,7 +5915,7 @@ namespace Slang if (auto targetDeclRefType = as<DeclRefType>(decl->targetType)) { // Attach our extension to that type as a candidate... - if (auto aggTypeDeclRef = targetDeclRefType->declRef.as<AggTypeDecl>()) + if (auto aggTypeDeclRef = targetDeclRefType->getDeclRef().as<AggTypeDecl>()) { auto aggTypeDecl = aggTypeDeclRef.getDecl(); @@ -6075,7 +5966,7 @@ namespace Slang continue; } - auto baseDeclRef = baseDeclRefType->declRef; + auto baseDeclRef = baseDeclRefType->getDeclRef(); auto baseInterfaceDeclRef = baseDeclRef.as<InterfaceDecl>(); if( !baseInterfaceDeclRef ) { @@ -6106,9 +5997,9 @@ namespace Slang // conform to the interface and fill in its // requirements. // - ThisType* thisType = m_astBuilder->create<ThisType>(); - thisType->interfaceDeclRef = interfaceDeclRef; - return thisType; + return DeclRefType::create( + m_astBuilder, + m_astBuilder->getDirectDeclRef(interfaceDeclRef.getDecl()->getThisTypeDecl())); } else if (auto aggTypeDeclRef = declRef.as<AggTypeDecl>()) { @@ -6159,7 +6050,7 @@ namespace Slang { if( auto declRefType = as<DeclRefType>(type) ) { - return calcThisType(declRefType->declRef); + return calcThisType(declRefType->getDeclRef()); } else { @@ -6404,7 +6295,7 @@ namespace Slang return parentGeneric; } - DeclRef<ExtensionDecl> SemanticsVisitor::ApplyExtensionToType( + DeclRef<ExtensionDecl> SemanticsVisitor::applyExtensionToType( ExtensionDecl* extDecl, Type* type) { @@ -6438,15 +6329,15 @@ namespace Slang if (!TryUnifyTypes(constraints, extDecl->targetType.Ptr(), type)) return DeclRef<ExtensionDecl>(); - auto constraintSubst = trySolveConstraintSystem(&constraints, makeDeclRef(extGenericDecl)); - if (!constraintSubst) + auto solvedDeclRef = trySolveConstraintSystem(&constraints, makeDeclRef(extGenericDecl), ArrayView<Val*>()); + if (!solvedDeclRef) { return DeclRef<ExtensionDecl>(); } // Construct a reference to the extension with our constraint variables // set as they were found by solving the constraint system. - extDeclRef = m_astBuilder->getSpecializedDeclRef<Decl>(extDecl, constraintSubst).as<ExtensionDecl>(); + extDeclRef = solvedDeclRef.as<ExtensionDecl>(); } // Now extract the target type from our (possibly specialized) extension decl-ref. @@ -6458,67 +6349,21 @@ namespace Slang // substitution to the extension decl-ref. if(auto targetDeclRefType = as<DeclRefType>(targetType)) { - if(auto targetInterfaceDeclRef = targetDeclRefType->declRef.as<InterfaceDecl>()) + if(auto targetInterfaceDeclRef = targetDeclRefType->getDeclRef().as<InterfaceDecl>()) { // Okay, the target type is an interface. // - // Is the type we want to apply to also an interface? - if(auto appDeclRefType = as<DeclRefType>(type)) + // Is the type we want to apply to a ThisType? + if(auto appDeclRefType = as<ThisType>(type)) { - if(auto appInterfaceDeclRef = appDeclRefType->declRef.as<InterfaceDecl>()) + if(auto thisTypeLookupDeclRef = SubstitutionSet(appDeclRefType->getDeclRef()).findLookupDeclRef()) { - if(appInterfaceDeclRef.getDecl() == targetInterfaceDeclRef.getDecl()) + if(thisTypeLookupDeclRef->getDecl() == targetInterfaceDeclRef.getDecl()) { // Looks like we have a match in the types, - // now let's see if we have a this-type substitution. - if(auto appThisTypeSubst = as<ThisTypeSubstitution>(appInterfaceDeclRef.getSubst())) - { - if(appThisTypeSubst->interfaceDecl == appInterfaceDeclRef.getDecl()) - { - // The type we want to apply to has a this-type substitution, - // and (by construction) the target type currently does not. - // - SLANG_ASSERT(!as<ThisTypeSubstitution>(targetInterfaceDeclRef.getSubst())); - - // We will create a new substitution to apply to the target type. - ThisTypeSubstitution* newTargetSubst = m_astBuilder->getOrCreateThisTypeSubstitution( - appThisTypeSubst->interfaceDecl, - appThisTypeSubst->witness, - targetInterfaceDeclRef.getSubst()); - - targetType = DeclRefType::create(m_astBuilder, - m_astBuilder->getSpecializedDeclRef<InterfaceDecl>(targetInterfaceDeclRef.getDecl(), newTargetSubst)); - - // Note: we are constructing a this-type substitution that - // we will apply to the extension declaration as well. - // This is not strictly allowed by our current representation - // choices, but we need it in order to make sure that - // references to the target type of the extension - // declaration have a chance to resolve the way we want them to. - - ThisTypeSubstitution* newExtSubst = m_astBuilder->getOrCreateThisTypeSubstitution( - appThisTypeSubst->interfaceDecl, - appThisTypeSubst->witness, - extDeclRef.getSubst()); - - extDeclRef = m_astBuilder->getSpecializedDeclRef<ExtensionDecl>( - extDeclRef.getDecl(), - newExtSubst); - - // TODO: Ideally we should also apply the chosen specialization to - // the decl-ref for the extension, so that subsequent lookup through - // the members of this extension will retain that substitution and - // be able to apply it. - // - // E.g., if an extension method returns a value of an associated - // type, then we'd want that to become specialized to a concrete - // type when using the extension method on a value of concrete type. - // - // The challenge here that makes me reluctant to just staple on - // such a substitution is that it wouldn't follow our implicit - // rules about where `ThisTypeSubstitution`s can appear. - } - } + // now let's see if `type`'s declref starts with a Lookup. + targetType = type; + extDeclRef = m_astBuilder->getLookupDeclRef(thisTypeLookupDeclRef->getWitness(), extDeclRef.getDecl()); } } } @@ -6641,7 +6486,6 @@ namespace Slang { if( auto namespaceDeclRef = declRefExpr->declRef.as<NamespaceDeclBase>() ) { - SLANG_ASSERT(!namespaceDeclRef.getSubst()); namespaceDecl = namespaceDeclRef.getDecl(); } } @@ -7007,7 +6851,7 @@ namespace Slang // the extension to the type and see if we succeed in // making a match. // - auto extDeclRef = ApplyExtensionToType(semantics, extDecl, aggType); + auto extDeclRef = applyExtensionToType(semantics, extDecl, aggType); if(!extDeclRef) continue; @@ -7065,8 +6909,8 @@ namespace Slang { if (auto andType = as<AndType>(type)) { - _getCanonicalConstraintTypes(outTypeList, andType->left); - _getCanonicalConstraintTypes(outTypeList, andType->right); + _getCanonicalConstraintTypes(outTypeList, andType->getLeft()); + _getCanonicalConstraintTypes(outTypeList, andType->getRight()); } else { @@ -7087,7 +6931,7 @@ namespace Slang assert( genericTypeConstraintDecl.getDecl()->sub.type->astNodeType == ASTNodeType::DeclRefType); - auto typeParamDecl = as<DeclRefType>(genericTypeConstraintDecl.getDecl()->sub.type)->declRef.getDecl(); + auto typeParamDecl = as<DeclRefType>(genericTypeConstraintDecl.getDecl()->sub.type)->getDeclRef().getDecl(); List<Type*>* constraintTypes = genericConstraints.tryGetValue(typeParamDecl); assert(constraintTypes); constraintTypes->add(genericTypeConstraintDecl.getDecl()->getSup().type); @@ -7107,42 +6951,6 @@ namespace Slang return result; } - Val* SemanticsDeclTypeResolutionVisitor::resolveVal(Val* val) - { - if (auto declRefType = as<DeclRefType>(val)) - { - if (auto concreteType = _tryLookupConcreteAssociatedTypeFromThisTypeSubst(m_astBuilder, declRefType->declRef)) - return as<Type>(concreteType); - for (auto subst = declRefType->declRef.getSubst(); subst; subst=subst->getOuter()) - { - if (auto genericSubst = as<GenericSubstitution>(subst)) - { - ShortList<Val*> newArgs; - for (auto& arg : genericSubst->getArgs()) - { - arg = resolveVal(arg); - SLANG_RELEASE_ASSERT(arg); - } - } - } - } - else if (auto subtypeWitness = as<SubtypeWitness>(val)) - { - auto sub = as<Type>(resolveVal(subtypeWitness->sub)); - auto sup = as<Type>(resolveVal(subtypeWitness->sup)); - if (sub && sup) - { - if (sub != subtypeWitness->sub || sup != subtypeWitness->sup) - { - auto newVal = tryGetSubtypeWitness(as<Type>(sub), as<Type>(sup)); - if (newVal) - val = newVal; - } - } - } - return val; - } - struct ArgsWithDirectionInfo { List<Expr*> args; |
