summaryrefslogtreecommitdiff
path: root/source/slang/slang-lookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-lookup.cpp')
-rw-r--r--source/slang/slang-lookup.cpp115
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`.