summaryrefslogtreecommitdiff
path: root/source/slang/slang-lookup.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-08-04 15:47:39 -0700
committerGitHub <noreply@github.com>2023-08-04 15:47:39 -0700
commita2d90fb275962da84611160f8ddd74d934a68dbd (patch)
tree066084537b9f4fe1f367de100ed6638a88a028c1 /source/slang/slang-lookup.cpp
parent17da4f0dec2b86ba3a4bdaf8a2ae112047d23623 (diff)
Redesign `DeclRef` and systematic `Val` deduplication (#3049)
* Redesign DeclRef + Deduplicate Val. * Update project files * Fix warning. * Fix. * Fix. * Remove `Val::_equalsImplOverride`. * Rmove `Val::_getHashCodeOverride`. * Remove `semanticVisitor` param from `resolve`. * Cleanups. --------- Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-lookup.cpp')
-rw-r--r--source/slang/slang-lookup.cpp146
1 files changed, 64 insertions, 82 deletions
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp
index 2eca91673..89d3380e4 100644
--- a/source/slang/slang-lookup.cpp
+++ b/source/slang/slang-lookup.cpp
@@ -16,7 +16,7 @@ void ensureDecl(SemanticsVisitor* visitor, Decl* decl, DeclCheckState state);
//
-DeclRef<ExtensionDecl> ApplyExtensionToType(
+DeclRef<ExtensionDecl> applyExtensionToType(
SemanticsVisitor* semantics,
ExtensionDecl* extDecl,
Type* type);
@@ -161,14 +161,12 @@ static bool _isUncheckedLocalVar(const Decl* decl)
static void _lookUpDirectAndTransparentMembers(
ASTBuilder* astBuilder,
Name* name,
- DeclRef<ContainerDecl> containerDeclRef,
+ ContainerDecl* containerDecl, // The container decl to find member with `name`.
+ DeclRef<Decl> parentDeclRef, // The parent of the resulting declref.
LookupRequest const& request,
LookupResult& result,
BreadcrumbInfo* inBreadcrumbs)
{
- ContainerDecl* containerDecl = containerDeclRef.getDecl();
-
-
if (request.isCompletionRequest())
{
// If we are looking up for completion suggestions,
@@ -182,7 +180,7 @@ static void _lookUpDirectAndTransparentMembers(
AddToLookupResult(
result,
CreateLookupResultItem(
- astBuilder->getSpecializedDeclRef<Decl>(member, containerDeclRef.getSubst()), inBreadcrumbs));
+ astBuilder->getMemberDeclRef<Decl>(parentDeclRef, member), inBreadcrumbs));
}
}
else
@@ -207,7 +205,7 @@ static void _lookUpDirectAndTransparentMembers(
continue;
// The declaration passed the test, so add it!
- AddToLookupResult(result, CreateLookupResultItem(astBuilder->getSpecializedDeclRef<Decl>(m, containerDeclRef.getSubst()), inBreadcrumbs));
+ AddToLookupResult(result, CreateLookupResultItem(astBuilder->getMemberDeclRef<Decl>(parentDeclRef, m), inBreadcrumbs));
}
}
@@ -215,9 +213,9 @@ static void _lookUpDirectAndTransparentMembers(
// if we already has a hit in the current container?
for(auto transparentInfo : containerDecl->getTransparentMembers())
{
- // The reference to the transparent member should use whatever
- // substitutions we used in referring to its outer container
- DeclRef<Decl> transparentMemberDeclRef = astBuilder->getSpecializedDeclRef(transparentInfo.decl, containerDeclRef.getSubst());
+ // The reference to the transparent member should use the same
+ // path as we used in referring to its parent.
+ DeclRef<Decl> transparentMemberDeclRef = astBuilder->getMemberDeclRef(parentDeclRef, transparentInfo.decl);
// We need to leave a breadcrumb so that we know that the result
// of lookup involves a member lookup step here
@@ -262,7 +260,8 @@ LookupResult lookUpDirectAndTransparentMembers(
ASTBuilder* astBuilder,
SemanticsVisitor* semantics,
Name* name,
- DeclRef<ContainerDecl> containerDeclRef,
+ ContainerDecl* containerDecl,
+ DeclRef<Decl> parentDeclRef,
LookupMask mask)
{
LookupRequest request = initLookupRequest(semantics, name, mask, LookupOptions::None, nullptr);
@@ -270,36 +269,14 @@ LookupResult lookUpDirectAndTransparentMembers(
_lookUpDirectAndTransparentMembers(
astBuilder,
name,
- containerDeclRef,
+ containerDecl,
+ parentDeclRef,
request,
result,
nullptr);
return result;
}
-static SubtypeWitness* _makeSubtypeWitness(
- ASTBuilder* astBuilder,
- Type* subType,
- SubtypeWitness* subToMidWitness,
- Type* superType,
- SubtypeWitness* midtoSuperWitness)
-{
- SLANG_UNUSED(subType);
- SLANG_UNUSED(superType);
-
- if(subToMidWitness)
- {
- auto transitiveWitness = astBuilder->getTransitiveSubtypeWitness(
- subToMidWitness,
- midtoSuperWitness);
- return transitiveWitness;
- }
- else
- {
- return midtoSuperWitness;
- }
-}
-
// Specialize `declRefToSpecialize` with ThisType info if `superType` is an interface type.
DeclRef<Decl> _maybeSpecializeSuperTypeDeclRef(
ASTBuilder* astBuilder,
@@ -309,14 +286,10 @@ DeclRef<Decl> _maybeSpecializeSuperTypeDeclRef(
{
if (auto superDeclRefType = as<DeclRefType>(superType))
{
- if (auto superInterfaceDeclRef = superDeclRefType->declRef.as<InterfaceDecl>())
+ if (auto superInterfaceDeclRef = superDeclRefType->getDeclRef().as<InterfaceDecl>())
{
- ThisTypeSubstitution* thisTypeSubst = astBuilder->getOrCreateThisTypeSubstitution(
- superInterfaceDeclRef.getDecl(),
- subIsSuperWitness,
- declRefToSpecialize.getSubst());
-
- auto specializedDeclRef = astBuilder->getSpecializedDeclRef<Decl>(declRefToSpecialize.getDecl(), thisTypeSubst);
+ ThisTypeDecl* thisTypeDecl = superInterfaceDeclRef.getDecl()->getThisTypeDecl();
+ auto specializedDeclRef = astBuilder->getLookupDeclRef(subIsSuperWitness, thisTypeDecl);
return specializedDeclRef;
}
@@ -332,7 +305,7 @@ static Type* _maybeSpecializeSuperType(
{
if (auto superDeclRefType = as<DeclRefType>(superType))
{
- auto specializedDeclRef = _maybeSpecializeSuperTypeDeclRef(astBuilder, superDeclRefType->declRef, superType, subIsSuperWitness);
+ auto specializedDeclRef = _maybeSpecializeSuperTypeDeclRef(astBuilder, superDeclRefType->getDeclRef(), superType, subIsSuperWitness);
return DeclRefType::create(astBuilder, specializedDeclRef);
}
@@ -391,14 +364,21 @@ static void _lookUpMembersInSuperType(
}
static void _lookUpMembersInSuperTypeDeclImpl(
- ASTBuilder* astBuilder,
- Name* name,
+ ASTBuilder* astBuilder,
+ Name* name,
DeclRef<Decl> declRef,
- LookupRequest const& request,
- LookupResult& ioResult,
- BreadcrumbInfo* inBreadcrumbs)
+ LookupRequest const& request,
+ LookupResult& ioResult,
+ BreadcrumbInfo* inBreadcrumbs)
{
auto semantics = request.semantics;
+ if (!as<InterfaceDecl>(declRef.getDecl()) && name->text == "This")
+ {
+ // If we are looking for `This` in anything other than an InterfaceDecl,
+ // we just need to return the declRef itself.
+ AddToLookupResult(ioResult, CreateLookupResultItem(declRef, inBreadcrumbs));
+ return;
+ }
// If the semantics context hasn't been established yet (e.g. when looking up during parsing),
// we simply do a direct lookup without considering subtypes or extensions.
@@ -408,7 +388,7 @@ static void _lookUpMembersInSuperTypeDeclImpl(
// In this case we can only lookup in an aggregate type.
if (auto aggTypeDeclBaseRef = declRef.as<AggTypeDeclBase>())
{
- _lookUpDirectAndTransparentMembers(astBuilder, name, aggTypeDeclBaseRef, request, ioResult, inBreadcrumbs);
+ _lookUpDirectAndTransparentMembers(astBuilder, name, aggTypeDeclBaseRef.getDecl(), aggTypeDeclBaseRef, request, ioResult, inBreadcrumbs);
}
return;
}
@@ -464,7 +444,7 @@ static void _lookUpMembersInSuperTypeDeclImpl(
// relying on the modifier.
if (auto declaredSubtypeWitness = as<DeclaredSubtypeWitness>(facet->subtypeWitness))
{
- auto inheritanceDeclRef = declaredSubtypeWitness->declRef;
+ auto inheritanceDeclRef = declaredSubtypeWitness->getDeclRef();
if (inheritanceDeclRef.getDecl()->hasModifier<IgnoreForLookupModifier>())
continue;
}
@@ -473,6 +453,7 @@ static void _lookUpMembersInSuperTypeDeclImpl(
BreadcrumbInfo* newBreadcrumbs = inBreadcrumbs;
BreadcrumbInfo subtypeInfo;
+ auto parentDeclRef = containerDeclRef;
if (facet->directness != Facet::Directness::Self)
{
// Depending on the type of the facet, we may want to specialize the
@@ -487,9 +468,15 @@ static void _lookUpMembersInSuperTypeDeclImpl(
// we should also specialize the interface declRef with the concrete
// type info.
//
- containerDeclRef = _maybeSpecializeSuperTypeDeclRef(
+ parentDeclRef = _maybeSpecializeSuperTypeDeclRef(
astBuilder, containerDeclRef, facet->getType(), facet->subtypeWitness)
.as<ContainerDecl>();
+ if (as<ThisTypeDecl>(parentDeclRef.getDecl()) && name->text == "This")
+ {
+ // If we are going looking for `This` in a `ThisType`, we just need to return the declRef itself.
+ AddToLookupResult(ioResult, CreateLookupResultItem(parentDeclRef, inBreadcrumbs));
+ continue;
+ }
// If we are looking up in a base type, we also need to make sure
// to create a breadcrumb to track the sub to super indirection.
@@ -502,7 +489,7 @@ static void _lookUpMembersInSuperTypeDeclImpl(
newBreadcrumbs = &subtypeInfo;
}
}
- _lookUpDirectAndTransparentMembers(astBuilder, name, containerDeclRef, request, ioResult, newBreadcrumbs);
+ _lookUpDirectAndTransparentMembers(astBuilder, name, containerDeclRef.getDecl(), parentDeclRef, request, ioResult, newBreadcrumbs);
}
}
@@ -540,7 +527,7 @@ static void _lookUpMembersInSuperTypeImpl(
if(auto declRefType = as<DeclRefType>(superType))
{
- auto declRef = declRefType->declRef;
+ auto declRef = declRefType->getDeclRef();
_lookUpMembersInSuperTypeDeclImpl(astBuilder, name, declRef, request, ioResult, inBreadcrumbs);
}
@@ -551,36 +538,16 @@ static void _lookUpMembersInSuperTypeImpl(
// lookup will have a comparable substitution applied (allowing things like associated
// types, etc. used in the signature of a method to resolve correctly).
//
- auto interfaceDeclRef = extractExistentialType->getSpecializedInterfaceDeclRef();
- _lookUpMembersInSuperTypeDeclImpl(astBuilder, name, 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->getThisTypeSubtypeWitness(superType, interfaceType);
-
- auto leafIsInterfaceWitness = _makeSubtypeWitness(
- astBuilder,
- leafType,
- leafIsSuperWitness,
- interfaceType,
- superIsInterfaceWitness);
-
- _lookUpMembersInSuperType(astBuilder, name, leafType, interfaceType, leafIsInterfaceWitness, request, ioResult, inBreadcrumbs);
+ auto thisTypeDeclRef = extractExistentialType->getThisTypeDeclRef();
+ _lookUpMembersInSuperTypeDeclImpl(astBuilder, name, thisTypeDeclRef, request, ioResult, inBreadcrumbs);
}
else if( auto andType = as<AndType>(superType) )
{
// We have a type of the form `leftType & rightType` and we need to perform
// lookup in both `leftType` and `rightType`.
//
- auto leftType = andType->left;
- auto rightType = andType->right;
+ auto leftType = andType->getLeft();
+ auto rightType = andType->getRight();
// Operationally, we are in a situation where we have a witness
// that the `leafType` we are doing lookup on is an subtype
@@ -731,7 +698,7 @@ static void _lookUpInScopes(
// just a decl.
//
DeclRef<ContainerDecl> containerDeclRef =
- astBuilder->getSpecializedDeclRef<Decl>(containerDecl, createDefaultSubstitutions(astBuilder, request.semantics, containerDecl)).as<ContainerDecl>();
+ createDefaultSubstitutionsIfNeeded(astBuilder, request.semantics, makeDeclRef(containerDecl)).as<ContainerDecl>();
// If the container we are looking into represents a type
// or an `extension` of a type, then we need to treat
@@ -755,7 +722,7 @@ static void _lookUpInScopes(
breadcrumb.thisParameterMode = thisParameterMode;
breadcrumb.declRef = aggTypeDeclBaseRef;
breadcrumb.prev = nullptr;
-
+ BreadcrumbInfo* breadcrumbPtr = &breadcrumb;
Type* type = nullptr;
if (auto extDeclRef = aggTypeDeclBaseRef.as<ExtensionDecl>())
{
@@ -773,10 +740,25 @@ static void _lookUpInScopes(
else
{
assert(aggTypeDeclBaseRef.as<AggTypeDecl>());
- type = DeclRefType::create(astBuilder, aggTypeDeclBaseRef);
+ if (auto interfaceBase = as<InterfaceDecl>(aggTypeDeclBaseRef.getDecl()))
+ {
+ // When looking up inside an interface type, we are actually looking up through ThisType.
+ if (name != interfaceBase->getThisTypeDecl()->getName())
+ {
+ type = DeclRefType::create(astBuilder, astBuilder->getMemberDeclRef(aggTypeDeclBaseRef, interfaceBase->getThisTypeDecl()));
+ // Don't need any breadcrumb for looking up through ThisType, since we have already
+ // created the base type reference in the new `type`'s declref.
+ breadcrumbPtr = nullptr;
+ }
+ }
+
+ if (!type)
+ {
+ type = DeclRefType::create(astBuilder, aggTypeDeclBaseRef);
+ }
}
- _lookUpMembersInType(astBuilder, name, type, request, result, &breadcrumb);
+ _lookUpMembersInType(astBuilder, name, type, request, result, breadcrumbPtr);
}
else
{
@@ -784,7 +766,7 @@ static void _lookUpInScopes(
// type or `extension` declaration, so we can look up members
// in that scope much more simply.
//
- _lookUpDirectAndTransparentMembers(astBuilder, name, containerDeclRef, request, result, nullptr);
+ _lookUpDirectAndTransparentMembers(astBuilder, name, containerDeclRef.getDecl(), containerDeclRef, request, result, nullptr);
}
// Before we proceed up to the next outer scope to perform lookup