Skip to content

Commit 6c2ccb4

Browse files
authored
reland: Fix RelBase indexing with composite types (#65550)
Previously the index data differed when using `Foo, Bar` vs `Foo & Bar`. Fixes #56255 This reverts commit 5e2c7a9.
1 parent 8f1b5c7 commit 6c2ccb4

File tree

3 files changed

+95
-6
lines changed

3 files changed

+95
-6
lines changed

lib/Index/Index.cpp

+33-5
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,18 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
962962
bool startEntityDecl(ValueDecl *D);
963963

964964
bool reportRelatedRef(ValueDecl *D, SourceLoc Loc, bool isImplicit, SymbolRoleSet Relations, Decl *Related);
965-
bool reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related);
965+
966+
/// Report references for dependent types
967+
///
968+
/// NOTE: If the dependent type is a typealias, report the underlying types as well.
969+
///
970+
/// \param Ty The type being referenced.
971+
/// \param Relations The relationship between the referenced type and the passed Decl.
972+
/// \param Related The Decl that is referencing the type.
973+
/// \param isImplicit Whether the reference is implicit, such as for a typealias' underlying type.
974+
/// \param Loc The location of the reference, otherwise the location of the TypeLoc is used.
975+
bool reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related,
976+
bool isImplicit=false, SourceLoc Loc={});
966977
bool reportInheritedTypeRefs(
967978
ArrayRef<InheritedEntry> Inherited, Decl *Inheritee);
968979

@@ -1377,20 +1388,37 @@ bool IndexSwiftASTWalker::reportInheritedTypeRefs(ArrayRef<InheritedEntry> Inher
13771388
return true;
13781389
}
13791390

1380-
bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations, Decl *Related) {
1381-
if (auto *declRefTR = dyn_cast_or_null<DeclRefTypeRepr>(Ty.getTypeRepr())) {
1382-
SourceLoc IdLoc = declRefTR->getLoc();
1391+
bool IndexSwiftASTWalker::reportRelatedTypeRef(const TypeLoc &Ty, SymbolRoleSet Relations,
1392+
Decl *Related, bool Implicit, SourceLoc Loc) {
1393+
if (auto *composite = llvm::dyn_cast_or_null<CompositionTypeRepr>(Ty.getTypeRepr())) {
1394+
SourceLoc IdLoc = Loc.isValid() ? Loc : composite->getSourceLoc();
1395+
for (auto *Type : composite->getTypes()) {
1396+
if (!reportRelatedTypeRef(Type, Relations, Related, /*isImplicit=*/Implicit, IdLoc))
1397+
return false;
1398+
}
1399+
1400+
return true;
1401+
} else if (auto *declRefTR = dyn_cast_or_null<DeclRefTypeRepr>(Ty.getTypeRepr())) {
1402+
SourceLoc IdLoc = Loc.isValid() ? Loc : declRefTR->getLoc();
13831403
NominalTypeDecl *NTD = nullptr;
1384-
bool isImplicit = false;
1404+
bool isImplicit = Implicit;
13851405
if (auto *VD = declRefTR->getBoundDecl()) {
13861406
if (auto *TAD = dyn_cast<TypeAliasDecl>(VD)) {
13871407
IndexSymbol Info;
1408+
if (isImplicit)
1409+
Info.roles |= (unsigned)SymbolRole::Implicit;
13881410
if (!reportRef(TAD, IdLoc, Info, None))
13891411
return false;
13901412
if (auto Ty = TAD->getUnderlyingType()) {
13911413
NTD = Ty->getAnyNominal();
13921414
isImplicit = true;
13931415
}
1416+
1417+
if (isa_and_nonnull<CompositionTypeRepr>(TAD->getUnderlyingTypeRepr())) {
1418+
TypeLoc TL(TAD->getUnderlyingTypeRepr(), TAD->getUnderlyingType());
1419+
if (!reportRelatedTypeRef(TL, Relations, Related, /*isImplicit=*/true, IdLoc))
1420+
return false;
1421+
}
13941422
} else {
13951423
NTD = dyn_cast<NominalTypeDecl>(VD);
13961424
}

test/Index/conformances.swift

+44-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protocol P3 {
5757
func meth2() // CHECK: [[@LINE]]:8 | instance-method/Swift | meth2() | [[P3_meth2_USR:.*]] | Def
5858
}
5959

60-
class BaseMultiConf {
60+
class BaseMultiConf { // CHECK: [[@LINE]]:7 | class/Swift | BaseMultiConf | [[BaseMultiConf_USR:.*]] | Def
6161
func meth2() {} // CHECK: [[@LINE]]:8 | instance-method/Swift | meth2() | [[BaseMultiConf_meth2_USR:.*]] | Def
6262
}
6363
extension SubMultiConf {
@@ -79,6 +79,49 @@ class SubMultiConf: BaseMultiConf,P2,P1,P3 { // CHECK: [[@LINE]]:7 | class/Swift
7979
// CHECK-NOT: [[@LINE-13]]:7 | instance-method
8080
}
8181

82+
class CompositionType: BaseMultiConf & P1 { // CHECK: [[@LINE]]:7 | class/Swift | CompositionType | [[CompositionType_USR:.*]] | Def
83+
// CHECK: [[@LINE-1]]:24 | class/Swift | BaseMultiConf | [[BaseMultiConf_USR]] | Ref,RelBase | rel: 1
84+
// CHECK: [[@LINE-2]]:24 | protocol/Swift | P1 | [[P1_USR]] | Ref,RelBase | rel: 1
85+
func foo() {}
86+
}
87+
88+
typealias CompositionTypeAlias = BaseMultiConf & P1 // CHECK: [[@LINE]]:11 | type-alias/Swift | CompositionTypeAlias | [[CompositionTypeAlias_USR:.*]] | Def
89+
// CHECK: [[@LINE-1]]:34 | class/Swift | BaseMultiConf | [[BaseMultiConf_USR]] | Ref | rel: 0
90+
// CHECK: [[@LINE-2]]:50 | protocol/Swift | P1 | [[P1_USR]] | Ref | rel: 0
91+
92+
class CompositionTypeViaAlias: CompositionTypeAlias { // CHECK: [[@LINE]]:7 | class/Swift | CompositionTypeViaAlias | [[CompositionTypeViaAlias_USR:.*]] | Def
93+
// CHECK: [[@LINE-1]]:32 | type-alias/Swift | CompositionTypeAlias | [[CompositionTypeAlias_USR]] | Ref | rel: 0
94+
// CHECK: [[@LINE-2]]:32 | class/Swift | BaseMultiConf | [[BaseMultiConf_USR]] | Ref,Impl,RelBase | rel: 1
95+
// CHECK: [[@LINE-3]]:32 | protocol/Swift | P1 | [[P1_USR]] | Ref,Impl,RelBase | rel: 1
96+
func foo() {}
97+
}
98+
99+
typealias NestedCompositionTypeAlias = CompositionTypeAlias & P2 // CHECK: [[@LINE]]:11 | type-alias/Swift | NestedCompositionTypeAlias | [[NestedCompositionTypeAlias_USR:.*]] | Def
100+
// CHECK: [[@LINE-1]]:40 | type-alias/Swift | CompositionTypeAlias | [[CompositionTypeAlias_USR]] | Ref | rel: 0
101+
// CHECK: [[@LINE-2]]:63 | protocol/Swift | P2 | [[P2_USR]] | Ref | rel: 0
102+
103+
class CompositionViaNestedAlias: NestedCompositionTypeAlias { // CHECK: [[@LINE]]:7 | class/Swift | CompositionViaNestedAlias | [[CompositionViaNestedAlias_USR:.*]] | Def
104+
// CHECK: [[@LINE-1]]:34 | type-alias/Swift | NestedCompositionTypeAlias | [[NestedCompositionTypeAlias_USR]] | Ref | rel: 0
105+
// CHECK: [[@LINE-2]]:34 | class/Swift | BaseMultiConf | [[BaseMultiConf_USR]] | Ref,Impl,RelBase | rel: 1
106+
// CHECK: [[@LINE-3]]:34 | protocol/Swift | P1 | [[P1_USR]] | Ref,Impl,RelBase | rel: 1
107+
// CHECK: [[@LINE-4]]:34 | protocol/Swift | P2 | [[P2_USR]] | Ref,Impl,RelBase | rel: 1
108+
func foo() {}
109+
}
110+
111+
typealias ProtocolsOnly = P1 & P2 // CHECK: [[@LINE]]:11 | type-alias/Swift | ProtocolsOnly | [[ProtocolsOnly_USR:.*]] | Def
112+
// CHECK: [[@LINE-1]]:27 | protocol/Swift | P1 | [[P1_USR]] | Ref | rel: 0
113+
// CHECK: [[@LINE-2]]:32 | protocol/Swift | P2 | [[P2_USR]] | Ref | rel: 0
114+
115+
class NoInherited {} // CHECK: [[@LINE]]:7 | class/Swift | NoInherited | [[NoInherited_USR:.*]] | Def
116+
extension NoInherited: ProtocolsOnly { // CHECK: [[@LINE]]:11 | class/Swift | NoInherited | [[NoInherited_USR:.*]] | Ref
117+
// CHECK: [[@LINE-1]]:24 | type-alias/Swift | ProtocolsOnly | [[ProtocolsOnly_USR]] | Ref | rel: 0
118+
// CHECK: [[@LINE-2]]:24 | protocol/Swift | P1 | [[P1_USR]] | Ref,Impl,RelBase | rel: 1
119+
// CHECK: [[@LINE-3]]:24 | protocol/Swift | P2 | [[P2_USR]] | Ref,Impl,RelBase | rel: 1
120+
func foo() {}
121+
}
122+
123+
struct WithCodable: Codable {} // CHECK: [[@LINE]]:21 | type-alias/Swift | Codable | [[Codable_USR:.*]] | Ref | rel: 0
124+
82125
protocol InheritingP: P1 { // CHECK: [[@LINE]]:10 | protocol/Swift | InheritingP | [[InheritingP_USR:.*]] | Def
83126
func foo() // CHECK: [[@LINE]]:8 | instance-method/Swift | foo() | [[InheritingP_foo_USR:.*]] | Def,Dyn,RelChild,RelOver | rel: 2
84127
// CHECK-NEXT: RelOver | instance-method/Swift | foo() | s:14swift_ide_test2P1P3fooyyF

test/Index/multifile.swift

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// Validate that we're not looking into typealises across files / modules which leads to an assertion
5+
6+
// RUN: %target-swift-frontend -index-store-path %t/idx -o %t/file.o -typecheck -primary-file %t/file2.swift %t/file1.swift -verify
7+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/file2.swift %t/file1.swift > %t/output.txt
8+
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %t/file1.swift %t/file2.swift >> %t/output.txt
9+
// RUN: %FileCheck %s < %t/output.txt
10+
11+
//--- file1.swift
12+
13+
typealias Bar = [Int] // CHECK: 2:11 | type-alias/Swift | Bar | [[Bar_USR:.*]] | Def | rel: 0
14+
15+
//--- file2.swift
16+
17+
func foo() -> Bar { [] } // CHECK: 2:15 | type-alias/Swift | Bar | [[Bar_USR]] | Ref,RelCont | rel: 1
18+
extension Optional where Wrapped == Bar {} // CHECK: 3:37 | type-alias/Swift | Bar | [[Bar_USR]] | Ref | rel: 0

0 commit comments

Comments
 (0)