From cbc1eff56057f199183bb7c17d8a360326512367 Mon Sep 17 00:00:00 2001 From: Yong He Date: Tue, 1 Nov 2022 08:46:57 -0700 Subject: Make `DifferentialPair` able to nest. (#2477) --- source/slang/slang-syntax.cpp | 67 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) (limited to 'source/slang/slang-syntax.cpp') diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp index c779b4510..8cd443438 100644 --- a/source/slang/slang-syntax.cpp +++ b/source/slang/slang-syntax.cpp @@ -319,7 +319,31 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt } } } - + else if (auto transitiveTypeWitness = as(subtypeWitness)) + { + // Hard code witness entry that `T.Differential = DifferentialBottom` for `T` that + // coerce to `DifferentialBottom`. + if (astBuilder->getDifferentialBottomType()->equals(transitiveTypeWitness->subToMid->sup)) + { + if (auto builtinAttr = requirementKey->findModifier()) + { + if (builtinAttr->kind == BuiltinRequirementKind::DifferentialType) + { + return RequirementWitness(astBuilder->getDifferentialBottomType()); + } + } + } + } + else if (auto extractFromConjunctionTypeWitness = as(subtypeWitness)) + { + if (auto conjunctionTypeWitness = as(extractFromConjunctionTypeWitness->conjunctionWitness)) + { + if (extractFromConjunctionTypeWitness->indexInConjunction == 0) + return tryLookUpRequirementWitness(astBuilder, as(conjunctionTypeWitness->leftWitness), requirementKey); + else + return tryLookUpRequirementWitness(astBuilder, as(conjunctionTypeWitness->rightWitness), requirementKey); + } + } // TODO: should handle the transitive case here too return RequirementWitness(); @@ -1140,7 +1164,46 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt return nullptr; } - // + Val* _tryLookupConcreteAssociatedTypeFromThisTypeSubst(ASTBuilder* builder, DeclRef declRef) + { + auto substDeclRef = declRef.as(); + if (!substDeclRef) + return nullptr; + + auto substAssocTypeDecl = substDeclRef.getDecl(); + + for (auto s = substDeclRef.substitutions.substitutions; s; s = s->outer) + { + auto thisSubst = as(s); + if (!thisSubst) + continue; + + if (auto interfaceDecl = as(substAssocTypeDecl->parentDecl)) + { + if (thisSubst->interfaceDecl == interfaceDecl) + { + // We need to look up the declaration that satisfies + // the requirement named by the associated type. + Decl* requirementKey = substAssocTypeDecl; + RequirementWitness requirementWitness = tryLookUpRequirementWitness(builder, thisSubst->witness, requirementKey); + switch (requirementWitness.getFlavor()) + { + default: + // No usable value was found, so there is nothing we can do. + break; + + case RequirementWitness::Flavor::val: + { + auto satisfyingVal = requirementWitness.getVal(); + return satisfyingVal; + } + break; + } + } + } + } + return nullptr; + } String DeclRefBase::toString() const { -- cgit v1.2.3