diff options
Diffstat (limited to 'source/slang/lookup.cpp')
| -rw-r--r-- | source/slang/lookup.cpp | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp index 95a1b3326..cf51ae720 100644 --- a/source/slang/lookup.cpp +++ b/source/slang/lookup.cpp @@ -323,6 +323,11 @@ void DoLookupImpl( // at the parameters themselves, so provide a fully-resolved // declaration reference for lookup. RefPtr<Substitutions> subst = nullptr; +#if 1 + // Actually, the above rationale seems bogus. If we are looking + // up from "inside" a generic declaration, we don't want to + // get its members pre-specialized, right? +#else if(auto parentGenericDecl = dynamic_cast<GenericDecl*>(containerDecl->ParentDecl)) { subst = new Substitutions(); @@ -342,6 +347,7 @@ void DoLookupImpl( } } } +#endif DeclRef<ContainerDecl> containerRef = DeclRef<Decl>(containerDecl, subst).As<ContainerDecl>(); DoLocalLookupImpl( @@ -370,7 +376,7 @@ LookupResult DoLookup( return result; } -LookupResult LookUp( +LookupResult lookUp( Session* session, SemanticsVisitor* semantics, Name* name, @@ -384,7 +390,7 @@ LookupResult LookUp( // perform lookup within the context of a particular container declaration, // and do *not* look further up the chain -LookupResult LookUpLocal( +LookupResult lookUpLocal( Session* session, SemanticsVisitor* semantics, Name* name, @@ -398,4 +404,72 @@ LookupResult LookUpLocal( return result; } +void lookUpMemberImpl( + Session* session, + SemanticsVisitor* semantics, + Name* name, + Type* type, + LookupResult& ioResult, + BreadcrumbInfo* inBreadcrumbs) +{ + if (auto declRefType = type->As<DeclRefType>()) + { + auto declRef = declRefType->declRef; + if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>()) + { + LookupRequest request; + request.semantics = semantics; + + DoLocalLookupImpl(session, name, aggTypeDeclRef, request, ioResult, inBreadcrumbs); + } + else if (auto genericTypeParamDeclRef = declRef.As<GenericTypeParamDecl>()) + { + auto genericDeclRef = genericTypeParamDeclRef.GetParent().As<GenericDecl>(); + assert(genericDeclRef); + + for(auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(genericDeclRef)) + { + // Does this constraint pertain to the type we are working on? + // + // We want constraints of the form `T : Foo` where `T` is the + // generic parameter in question, and `Foo` is whatever we are + // constraining it to. + auto subType = GetSub(constraintDeclRef); + auto subDeclRefType = subType->As<DeclRefType>(); + if(!subDeclRefType) + continue; + if(!subDeclRefType->declRef.Equals(genericTypeParamDeclRef)) + continue; + + // The super-type in the constraint (e.g., `Foo` in `T : Foo`) + // will tell us a type we should use for lookup. + auto bound = GetSup(constraintDeclRef); + + // Go ahead and use the target type, with an appropriate breadcrumb + // to indicate that we indirected through a type constraint. + + BreadcrumbInfo breadcrumb; + breadcrumb.prev = inBreadcrumbs; + breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::Constraint; + breadcrumb.declRef = constraintDeclRef; + + // TODO: Need to consider case where this might recurse infinitely. + lookUpMemberImpl(session, semantics, name, bound, ioResult, &breadcrumb); + } + } + } +} + +LookupResult lookUpMember( + Session* session, + SemanticsVisitor* semantics, + Name* name, + Type* type) +{ + LookupResult result; + lookUpMemberImpl(session, semantics, name, type, result, nullptr); + return result; +} + + } |
