diff options
| -rw-r--r-- | source/slang/check.cpp | 26 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 4 | ||||
| -rw-r--r-- | source/slang/lookup.cpp | 7 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 31 | ||||
| -rw-r--r-- | source/slang/syntax.h | 3 | ||||
| -rw-r--r-- | source/slang/val-defs.h | 12 |
6 files changed, 72 insertions, 11 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index f7bb2ae1f..3fe4f8c5d 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -1681,7 +1681,7 @@ namespace Slang { // TODO: actually implement matching here. For now we'll // just pretend that things are satisfied in order to make progress.. - requirementDict.Add(requiredMemberDeclRef, DeclRef<Decl>(memberDecl, nullptr)); + requirementDict.AddIfNotExists(requiredMemberDeclRef, DeclRef<Decl>(memberDecl, nullptr)); return true; } @@ -1927,10 +1927,16 @@ namespace Slang // (via the given `inheritanceDecl`) actually provides // members to satisfy all the requirements in the interface. bool checkInterfaceConformance( + HashSet<DeclRef<InterfaceDecl>> & checkedInterfaceDeclRef, DeclRef<AggTypeDeclBase> typeDeclRef, InheritanceDecl* inheritanceDecl, DeclRef<InterfaceDecl> interfaceDeclRef) { + if (!checkedInterfaceDeclRef.Contains(interfaceDeclRef)) + checkedInterfaceDeclRef.Add(interfaceDeclRef); + else + return true; + bool result = true; // We need to check the declaration of the interface @@ -1960,6 +1966,7 @@ namespace Slang // // TODO: we *really* need a linearization step here!!!! result = result && checkConformanceToType( + checkedInterfaceDeclRef, typeDeclRef, inheritanceDecl, getBaseType(requiredInheritanceDeclRef)); @@ -1985,6 +1992,7 @@ namespace Slang } bool checkConformanceToType( + HashSet<DeclRef<InterfaceDecl>>& checkedInterfaceDeclRefs, DeclRef<AggTypeDeclBase> typeDeclRef, InheritanceDecl* inheritanceDecl, Type* baseType) @@ -1998,6 +2006,7 @@ namespace Slang // We need to check that it provides all of the members // required by that interface. return checkInterfaceConformance( + checkedInterfaceDeclRefs, typeDeclRef, inheritanceDecl, baseInterfaceDeclRef); @@ -2019,7 +2028,8 @@ namespace Slang // Look at the type being inherited from, and validate // appropriately. auto baseType = inheritanceDecl->base.type; - return checkConformanceToType(typeDecl, inheritanceDecl, baseType.As<Type>()); + HashSet<DeclRef<InterfaceDecl>> checkdInterfaceDeclRefs; + return checkConformanceToType(checkdInterfaceDeclRefs, typeDecl, inheritanceDecl, baseType.As<Type>()); } bool checkConformance( @@ -2107,7 +2117,6 @@ namespace Slang { checkDecl(member); } - decl->SetCheckState(getCheckedState()); } @@ -4672,9 +4681,12 @@ namespace Slang // Create a witness that attests to the fact that `type` // is equal to itself. RefPtr<Val> createTypeEqualityWitness( - Type* /*type*/) + Type* type) { - SLANG_UNEXPECTED("unimplemented"); + RefPtr<TypeEqualityWitness> rs = new TypeEqualityWitness(); + rs->sub = type; + rs->sup = type; + return rs; } // If `sub` is a subtype of `sup`, then return a value that @@ -7141,4 +7153,8 @@ namespace Slang return subst; } + void checkDecl(SemanticsVisitor* visitor, Decl* decl) + { + visitor->checkDecl(decl); + } } diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 45ad71b67..f65af2ba4 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -4889,8 +4889,10 @@ namespace Slang { if (auto subDeclRefType = subtypeWitness->sub.As<DeclRefType>()) { - auto genericWitnessTableName = getMangledNameForConformanceWitness(DeclRef<Decl>(subDeclRefType->declRef.getDecl(), nullptr), subtypeWitness->sup); + auto defaultSubst = createDefaultSubstitutions(entryPointRequest->compileRequest->mSession, subDeclRefType->declRef.getDecl()); + auto genericWitnessTableName = getMangledNameForConformanceWitness(DeclRef<Decl>(subDeclRefType->declRef.getDecl(), defaultSubst), subtypeWitness->sup); table = findWitnessTableByName(genericWitnessTableName); + SLANG_ASSERT(table); WitnessTableSpecializationWorkItem workItem; workItem.srcTable = (IRWitnessTable*)table; workItem.dstTable = context->builder->createWitnessTable(); diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index 5f925a1c2..e5ffa00f7 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -4,6 +4,8 @@ namespace Slang { +void checkDecl(SemanticsVisitor* visitor, Decl* decl); + // DeclRef<ExtensionDecl> ApplyExtensionToType( @@ -224,6 +226,10 @@ void DoLocalLookupImpl( LookupResult& result, BreadcrumbInfo* inBreadcrumbs) { + if (result.lookedupDecls.Contains(containerDeclRef)) + return; + result.lookedupDecls.Add(containerDeclRef); + ContainerDecl* containerDecl = containerDeclRef.getDecl(); // Ensure that the lookup dictionary in the container is up to date @@ -318,6 +324,7 @@ void DoLocalLookupImpl( auto baseInterfaces = getMembersOfType<InheritanceDecl>(containerDeclRef); for (auto inheritanceDeclRef : baseInterfaces) { + checkDecl(request.semantics, inheritanceDeclRef.decl); auto baseType = inheritanceDeclRef.getDecl()->base.type.As<DeclRefType>(); SLANG_ASSERT(baseType); int diff = 0; diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index 2ed10e138..552f1dc56 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -1673,6 +1673,32 @@ void Type::accept(IValVisitor* visitor, void* extra) // TODO: should really have a `type.cpp` and a `witness.cpp` + bool TypeEqualityWitness::EqualsVal(Val* val) + { + auto otherWitness = dynamic_cast<TypeEqualityWitness*>(val); + if (!otherWitness) + return false; + return sub->Equals(otherWitness->sub); + } + + RefPtr<Val> TypeEqualityWitness::SubstituteImpl(SubstitutionSet subst, int * ioDiff) + { + RefPtr<TypeEqualityWitness> rs = new TypeEqualityWitness(); + rs->sub = sub->SubstituteImpl(subst, ioDiff).As<Type>(); + rs->sup = sup->SubstituteImpl(subst, ioDiff).As<Type>(); + return rs; + } + + String TypeEqualityWitness::ToString() + { + return "TypeEqualityWitness(" + sub->ToString() + ")"; + } + + int TypeEqualityWitness::GetHashCode() + { + return sub->GetHashCode(); + } + bool DeclaredSubtypeWitness::EqualsVal(Val* val) { auto otherWitness = dynamic_cast<DeclaredSubtypeWitness*>(val); @@ -1760,10 +1786,7 @@ void Type::accept(IValVisitor* visitor, void* extra) int DeclaredSubtypeWitness::GetHashCode() { - auto hash = sub->GetHashCode(); - hash = combineHash(hash, sup->GetHashCode()); - hash = combineHash(hash, declRef.GetHashCode()); - return hash; + return declRef.GetHashCode(); } // TransitiveSubtypeWitness diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 93e421977..b37301dec 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -969,6 +969,8 @@ namespace Slang // used at all, to avoid allocation. List<LookupResultItem> items; + HashSet<DeclRef<ContainerDecl>> lookedupDecls; + // Was at least one result found? bool isValid() const { return item.declRef.getDecl() != nullptr; } @@ -1009,7 +1011,6 @@ namespace Slang struct LookupRequest { SemanticsVisitor* semantics = nullptr; - RefPtr<Scope> scope = nullptr; RefPtr<Scope> endScope = nullptr; diff --git a/source/slang/val-defs.h b/source/slang/val-defs.h index 1fe3bfe44..d83cda85c 100644 --- a/source/slang/val-defs.h +++ b/source/slang/val-defs.h @@ -90,6 +90,18 @@ ABSTRACT_SYNTAX_CLASS(SubtypeWitness, Witness) ) END_SYNTAX_CLASS() +SYNTAX_CLASS(TypeEqualityWitness, SubtypeWitness) +RAW( + virtual bool EqualsVal(Val* val) override; + virtual String ToString() override; + virtual int GetHashCode() override; + virtual RefPtr<Val> SubstituteImpl(SubstitutionSet subst, int * ioDiff) override; + virtual DeclRef<Decl> getLastStepDeclRef() override + { + return DeclRef<Decl>(); + } +) +END_SYNTAX_CLASS() // A witness that one type is a subtype of another // because some in-scope declaration says so SYNTAX_CLASS(DeclaredSubtypeWitness, SubtypeWitness) |
