diff options
| author | Yong He <yonghe@outlook.com> | 2022-11-01 08:46:57 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-01 08:46:57 -0700 |
| commit | cbc1eff56057f199183bb7c17d8a360326512367 (patch) | |
| tree | 487865e928cd2ceecbb509f0bfd06aa8d9584411 /source/slang/slang-syntax.cpp | |
| parent | b707a07b1de3535cb0a8ccb6fe2ed4afa4a016d1 (diff) | |
Make `DifferentialPair` able to nest. (#2477)
Diffstat (limited to 'source/slang/slang-syntax.cpp')
| -rw-r--r-- | source/slang/slang-syntax.cpp | 67 |
1 files changed, 65 insertions, 2 deletions
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<TransitiveSubtypeWitness>(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<BuiltinRequirementAttribute>()) + { + if (builtinAttr->kind == BuiltinRequirementKind::DifferentialType) + { + return RequirementWitness(astBuilder->getDifferentialBottomType()); + } + } + } + } + else if (auto extractFromConjunctionTypeWitness = as<ExtractFromConjunctionSubtypeWitness>(subtypeWitness)) + { + if (auto conjunctionTypeWitness = as<ConjunctionSubtypeWitness>(extractFromConjunctionTypeWitness->conjunctionWitness)) + { + if (extractFromConjunctionTypeWitness->indexInConjunction == 0) + return tryLookUpRequirementWitness(astBuilder, as<SubtypeWitness>(conjunctionTypeWitness->leftWitness), requirementKey); + else + return tryLookUpRequirementWitness(astBuilder, as<SubtypeWitness>(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<Decl> declRef) + { + auto substDeclRef = declRef.as<AssocTypeDecl>(); + if (!substDeclRef) + return nullptr; + + auto substAssocTypeDecl = substDeclRef.getDecl(); + + for (auto s = substDeclRef.substitutions.substitutions; s; s = s->outer) + { + auto thisSubst = as<ThisTypeSubstitution>(s); + if (!thisSubst) + continue; + + if (auto interfaceDecl = as<InterfaceDecl>(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 { |
