diff options
Diffstat (limited to 'source/slang/slang-lookup.cpp')
| -rw-r--r-- | source/slang/slang-lookup.cpp | 115 |
1 files changed, 80 insertions, 35 deletions
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp index a17ba0ba2..3aab22724 100644 --- a/source/slang/slang-lookup.cpp +++ b/source/slang/slang-lookup.cpp @@ -22,6 +22,7 @@ struct BreadcrumbInfo LookupResultItem::Breadcrumb::Kind kind; LookupResultItem::Breadcrumb::ThisParameterMode thisParameterMode = LookupResultItem::Breadcrumb::ThisParameterMode::Default; DeclRef<Decl> declRef; + Val* val = nullptr; BreadcrumbInfo* prev = nullptr; }; @@ -165,6 +166,7 @@ LookupResultItem CreateLookupResultItem( breadcrumbs = new LookupResultItem::Breadcrumb( bb->kind, bb->declRef, + bb->val, breadcrumbs, bb->thisParameterMode); } @@ -267,33 +269,42 @@ LookupResult lookUpDirectAndTransparentMembers( return result; } - static SubtypeWitness* _makeSubtypeWitness( ASTBuilder* astBuilder, Type* subType, SubtypeWitness* subToMidWitness, Type* superType, - DeclRef<TypeConstraintDecl> midToSuperConstraint) + SubtypeWitness* midtoSuperWitness) { if(subToMidWitness) { TransitiveSubtypeWitness* transitiveWitness = astBuilder->create<TransitiveSubtypeWitness>(); transitiveWitness->subToMid = subToMidWitness; - transitiveWitness->midToSup = midToSuperConstraint; + transitiveWitness->midToSup = midtoSuperWitness; transitiveWitness->sub = subType; transitiveWitness->sup = superType; return transitiveWitness; } else { - DeclaredSubtypeWitness* declaredWitness = astBuilder->create<DeclaredSubtypeWitness>(); - declaredWitness->declRef = midToSuperConstraint; - declaredWitness->sub = subType; - declaredWitness->sup = superType; - return declaredWitness; + return midtoSuperWitness; } } +static SubtypeWitness* _makeSubtypeWitness( + ASTBuilder* astBuilder, + Type* subType, + SubtypeWitness* subToMidWitness, + Type* superType, + DeclRef<TypeConstraintDecl> midToSuperConstraint) +{ + DeclaredSubtypeWitness* midToSuperWitness = astBuilder->create<DeclaredSubtypeWitness>(); + midToSuperWitness->declRef = midToSuperConstraint; + midToSuperWitness->sub = subType; + midToSuperWitness->sup = superType; + return _makeSubtypeWitness(astBuilder, subType, subToMidWitness, superType, midToSuperWitness); +} + // Same as the above, but we are specializing a type instead of a decl-ref static Type* _maybeSpecializeSuperType( ASTBuilder* astBuilder, @@ -337,37 +348,16 @@ static void _lookUpMembersInSuperTypeImpl( LookupResult& ioResult, BreadcrumbInfo* inBreadcrumbs); - static void _lookUpMembersInSuperType( - ASTBuilder* astBuilder, + ASTBuilder* astBuilder, Name* name, Type* leafType, - SubtypeWitness* leafIsIntermediateWitness, - DeclRef<TypeConstraintDecl> intermediateIsSuperConstraint, + Type* superType, + SubtypeWitness* leafIsSuperWitness, LookupRequest const& request, LookupResult& ioResult, BreadcrumbInfo* inBreadcrumbs) { - if( request.semantics ) - { - ensureDecl(request.semantics, intermediateIsSuperConstraint, DeclCheckState::CanUseBaseOfInheritanceDecl); - } - - // The super-type in the constraint (e.g., `Foo` in `T : Foo`) - // will tell us a type we should use for lookup. - // - auto superType = getSup(astBuilder, intermediateIsSuperConstraint); - // - // We will go ahead and perform lookup using `superType`, - // after dealing with some details. - - auto leafIsSuperWitness = _makeSubtypeWitness( - astBuilder, - leafType, - leafIsIntermediateWitness, - superType, - intermediateIsSuperConstraint); - // If we are looking up through an interface type, then // we need to be sure that we add an appropriate // "this type" substitution here, since that needs to @@ -384,8 +374,8 @@ static void _lookUpMembersInSuperType( // BreadcrumbInfo breadcrumb; breadcrumb.prev = inBreadcrumbs; - breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::Constraint; - breadcrumb.declRef = intermediateIsSuperConstraint; + breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::SuperType; + breadcrumb.val = leafIsSuperWitness; breadcrumb.prev = inBreadcrumbs; // TODO: Need to consider case where this might recurse infinitely (e.g., @@ -399,6 +389,39 @@ static void _lookUpMembersInSuperType( _lookUpMembersInSuperTypeImpl(astBuilder, name, leafType, superType, leafIsSuperWitness, request, ioResult, &breadcrumb); } +static void _lookUpMembersInSuperType( + ASTBuilder* astBuilder, + Name* name, + Type* leafType, + SubtypeWitness* leafIsIntermediateWitness, + DeclRef<TypeConstraintDecl> intermediateIsSuperConstraint, + LookupRequest const& request, + LookupResult& ioResult, + BreadcrumbInfo* inBreadcrumbs) +{ + if( request.semantics ) + { + ensureDecl(request.semantics, intermediateIsSuperConstraint, DeclCheckState::CanUseBaseOfInheritanceDecl); + } + + // The super-type in the constraint (e.g., `Foo` in `T : Foo`) + // will tell us a type we should use for lookup. + // + auto superType = getSup(astBuilder, intermediateIsSuperConstraint); + // + // We will go ahead and perform lookup using `superType`, + // after dealing with some details. + + auto leafIsSuperWitness = _makeSubtypeWitness( + astBuilder, + leafType, + leafIsIntermediateWitness, + superType, + intermediateIsSuperConstraint); + + return _lookUpMembersInSuperType(astBuilder, name, leafType, superType, leafIsSuperWitness, request, ioResult, inBreadcrumbs); +} + static void _lookUpMembersInSuperTypeDeclImpl( ASTBuilder* astBuilder, Name* name, @@ -587,10 +610,32 @@ static void _lookUpMembersInSuperTypeImpl( _lookUpMembersInSuperTypeDeclImpl(astBuilder, name, leafType, superType, leafIsSuperWitness, declRef, request, ioResult, inBreadcrumbs); } - if (auto extractExistentialType = as<ExtractExistentialType>(superType)) + else if (auto extractExistentialType = as<ExtractExistentialType>(superType)) { _lookUpMembersInSuperTypeDeclImpl(astBuilder, name, leafType, superType, leafIsSuperWitness, extractExistentialType->interfaceDeclRef, request, ioResult, inBreadcrumbs); } + else if( auto thisType = as<ThisType>(superType) ) + { + // We need to create a witness that represents the next link in the + // chain. The `leafIsSuperWitness` represents the knowledge that `leafType : superType` + // (and we know that `superType == thisType`, but we now need to extend that + // with the knowledge that `thisType : thisType->interfaceTypeDeclRef`. + // + auto interfaceType = DeclRefType::create(astBuilder, thisType->interfaceDeclRef); + + auto superIsInterfaceWitness = astBuilder->create<ThisTypeSubtypeWitness>(); + superIsInterfaceWitness->sub = superType; + superIsInterfaceWitness->sup = interfaceType; + + auto leafIsInterfaceWitness = _makeSubtypeWitness( + astBuilder, + leafType, + leafIsSuperWitness, + interfaceType, + superIsInterfaceWitness); + + _lookUpMembersInSuperTypeDeclImpl(astBuilder, name, leafType, interfaceType, leafIsInterfaceWitness, thisType->interfaceDeclRef, request, ioResult, inBreadcrumbs); + } } /// Perform lookup for `name` in the context of `type`. |
