Skip to content

Commit 981167d

Browse files
committed
[index] Add back override relation for associated type witnesses
When conforming to a protocol, the index should have a "override" relation for each witness, including type witnesses. This was accidentally broken in 3bd80e5 when we stopped using the type-checker to find all protocol conformances. rdar://47833618
1 parent ada9d92 commit 981167d

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

lib/Index/Index.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class SourceFileOrModule {
129129
}
130130
};
131131

132-
struct ValueWitness {
132+
struct IndexedWitness {
133133
ValueDecl *Member;
134134
ValueDecl *Requirement;
135135
};
@@ -146,7 +146,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
146146
Decl *D;
147147
SymbolInfo SymInfo;
148148
SymbolRoleSet Roles;
149-
SmallVector<ValueWitness, 6> ExplicitValueWitnesses;
149+
SmallVector<IndexedWitness, 6> ExplicitWitnesses;
150150
SmallVector<SourceLoc, 6> RefsToSuppress;
151151
};
152152
SmallVector<Entity, 6> EntitiesStack;
@@ -462,8 +462,8 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
462462
bool reportExtension(ExtensionDecl *D);
463463
bool reportRef(ValueDecl *D, SourceLoc Loc, IndexSymbol &Info,
464464
Optional<AccessKind> AccKind);
465-
bool reportImplicitValueConformance(ValueDecl *witness, ValueDecl *requirement,
466-
Decl *container);
465+
bool reportImplicitConformance(ValueDecl *witness, ValueDecl *requirement,
466+
Decl *container);
467467

468468
bool startEntity(Decl *D, IndexSymbol &Info, bool IsRef);
469469
bool startEntityDecl(ValueDecl *D);
@@ -535,7 +535,7 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
535535
/// members.
536536
///
537537
/// \returns false if AST visitation should stop.
538-
bool handleValueWitnesses(Decl *D, SmallVectorImpl<ValueWitness> &explicitValueWitnesses);
538+
bool handleWitnesses(Decl *D, SmallVectorImpl<IndexedWitness> &explicitWitnesses);
539539

540540
void getModuleHash(SourceFileOrModule SFOrMod, llvm::raw_ostream &OS);
541541
llvm::hash_code hashModule(llvm::hash_code code, SourceFileOrModule SFOrMod);
@@ -696,7 +696,7 @@ bool IndexSwiftASTWalker::visitImports(
696696
return true;
697697
}
698698

699-
bool IndexSwiftASTWalker::handleValueWitnesses(Decl *D, SmallVectorImpl<ValueWitness> &explicitValueWitnesses) {
699+
bool IndexSwiftASTWalker::handleWitnesses(Decl *D, SmallVectorImpl<IndexedWitness> &explicitWitnesses) {
700700
auto DC = dyn_cast<DeclContext>(D);
701701
if (!DC)
702702
return true;
@@ -720,11 +720,26 @@ bool IndexSwiftASTWalker::handleValueWitnesses(Decl *D, SmallVectorImpl<ValueWit
720720
return;
721721

722722
if (decl->getDeclContext() == DC) {
723-
explicitValueWitnesses.push_back(ValueWitness{decl, req});
723+
explicitWitnesses.push_back({decl, req});
724+
} else {
725+
reportImplicitConformance(decl, req, D);
726+
}
727+
});
728+
729+
normal->forEachTypeWitness(nullptr,
730+
[&](AssociatedTypeDecl *assoc, Type type, TypeDecl *typeDecl) {
731+
if (Cancelled)
732+
return true;
733+
if (typeDecl == nullptr)
734+
return false;
735+
736+
if (typeDecl->getDeclContext() == DC) {
737+
explicitWitnesses.push_back({typeDecl, assoc});
724738
} else {
725739
// Report the implicit conformance.
726-
reportImplicitValueConformance(decl, req, D);
740+
reportImplicitConformance(typeDecl, assoc, D);
727741
}
742+
return false;
728743
});
729744
}
730745

@@ -742,12 +757,12 @@ bool IndexSwiftASTWalker::startEntity(Decl *D, IndexSymbol &Info, bool IsRef) {
742757
case swift::index::IndexDataConsumer::Skip:
743758
return false;
744759
case swift::index::IndexDataConsumer::Continue: {
745-
SmallVector<ValueWitness, 6> explicitValueWitnesses;
760+
SmallVector<IndexedWitness, 6> explicitWitnesses;
746761
if (!IsRef) {
747-
if (!handleValueWitnesses(D, explicitValueWitnesses))
762+
if (!handleWitnesses(D, explicitWitnesses))
748763
return false;
749764
}
750-
EntitiesStack.push_back({D, Info.symInfo, Info.roles, std::move(explicitValueWitnesses), {}});
765+
EntitiesStack.push_back({D, Info.symInfo, Info.roles, std::move(explicitWitnesses), {}});
751766
return true;
752767
}
753768
}
@@ -782,7 +797,7 @@ bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
782797
}
783798

784799
if (auto Parent = getParentDecl()) {
785-
for (const ValueWitness &witness : EntitiesStack.back().ExplicitValueWitnesses) {
800+
for (const IndexedWitness &witness : EntitiesStack.back().ExplicitWitnesses) {
786801
if (witness.Member == D)
787802
addRelation(Info, (SymbolRoleSet) SymbolRole::RelationOverrideOf, witness.Requirement);
788803
}
@@ -1105,8 +1120,8 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc,
11051120
return finishCurrentEntity();
11061121
}
11071122

1108-
bool IndexSwiftASTWalker::reportImplicitValueConformance(ValueDecl *witness, ValueDecl *requirement,
1109-
Decl *container) {
1123+
bool IndexSwiftASTWalker::reportImplicitConformance(ValueDecl *witness, ValueDecl *requirement,
1124+
Decl *container) {
11101125
if (!shouldIndex(witness, /*IsRef=*/true))
11111126
return true; // keep walking
11121127

test/Index/conformances.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,29 @@ extension InheritingP { // CHECK: [[@LINE]]:11 | extension/ext-protocol/Swift |
9898
// CHECK-NEXT: RelOver | instance-method/Swift | foo() | [[InheritingP_foo_USR]]
9999
// CHECK-NEXT: RelChild | extension/ext-protocol/Swift | InheritingP | [[InheritingP_USR]]
100100
}
101+
102+
protocol WithAssocType {
103+
associatedtype T // CHECK: [[@LINE]]:18 | type-alias/associated-type/Swift | T | [[WithAssocT_USR:.*]] | Def
104+
func foo() -> T // CHECK: [[@LINE]]:17 | type-alias/associated-type/Swift | T | [[WithAssocT_USR]] | Ref
105+
}
106+
107+
struct SAssocTypeAlias: WithAssocType {
108+
typealias T = Int // CHECK: [[@LINE]]:13 | type-alias/Swift | T | [[SAssocT:.*]] | Def,RelChild,RelOver | rel: 2
109+
// CHECK-NEXT: RelOver | type-alias/associated-type/Swift | T | [[WithAssocT_USR]]
110+
// CHECK-NEXT: RelChild | struct/Swift | SAssocTypeAlias
111+
func foo() -> T { return 0 } // CHECK: [[@LINE]]:17 | type-alias/Swift | T | [[SAssocT:.*]] | Ref
112+
}
113+
114+
struct SAssocTypeInferred: WithAssocType {
115+
func foo() -> Int { return 1 }
116+
func bar() -> T { return 2 } // CHECK: [[@LINE]]:17 | type-alias/associated-type/Swift | T | [[WithAssocT_USR]] | Ref
117+
}
118+
119+
struct AssocViaExtension {
120+
struct T {} // CHECK: [[@LINE]]:10 | struct/Swift | T | [[AssocViaExtensionT_USR:.*]] | Def
121+
func foo() -> T { return T() }
122+
}
123+
124+
extension AssocViaExtension: WithAssocType {} // CHECK: [[@LINE]]:11 | struct/Swift | T | [[AssocViaExtensionT_USR]] | Impl,RelOver,RelCont | rel: 2
125+
// CHECK-NEXT: RelOver | type-alias/associated-type/Swift | T | [[WithAssocT_USR]]
126+
// CHECK-NEXT: RelCont | extension/ext-struct/Swift | AssocViaExtension

0 commit comments

Comments
 (0)