Skip to content

Commit df035eb

Browse files
committed
[RelatedIdents] Fix an assertion failure if two invalid declarations have the same base name
We need to check both the USR and the display name because multiple distinct decls might have the same USR. For example, the following declarations have the same USR with a single ERROR_TYPE parameter despite being distinct declarations. ```swift func bar(body: Invalid) {} func bar(ignoreCase: Bool, body: Invalid) {} ``` The display name contains the argument labels, which is sufficient to distinguish these declarations. rdar://126803702
1 parent c2a5028 commit df035eb

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

include/swift/Index/Index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace index {
2525
void indexDeclContext(DeclContext *DC, IndexDataConsumer &consumer);
2626
void indexSourceFile(SourceFile *SF, IndexDataConsumer &consumer);
2727
void indexModule(ModuleDecl *module, IndexDataConsumer &consumer);
28+
bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS);
2829

2930
} // end namespace index
3031
} // end namespace swift

lib/Index/Index.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ printArtificialName(const swift::AbstractStorageDecl *ASD, AccessorKind AK, llvm
7373
llvm_unreachable("Unhandled AccessorKind in switch.");
7474
}
7575

76-
static bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
76+
bool index::printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
7777
if (!D->hasName() && !isa<ParamDecl>(D)) {
7878
auto *FD = dyn_cast<AccessorDecl>(D);
7979
if (!FD)

lib/Refactoring/LocalRename.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ swift::ide::getRenameInfo(ResolvedCursorInfoPtr cursorInfo) {
194194
}
195195

196196
class RenameRangeCollector : public IndexDataConsumer {
197-
StringRef usr;
197+
SmallString<64> usr;
198+
SmallString<64> displayName;
198199
std::unique_ptr<StringScratchSpace> stringStorage;
199200
std::vector<RenameLoc> locations;
200201

@@ -204,10 +205,11 @@ class RenameRangeCollector : public IndexDataConsumer {
204205

205206
RenameRangeCollector(const ValueDecl *D)
206207
: stringStorage(new StringScratchSpace()) {
207-
SmallString<64> SS;
208-
llvm::raw_svector_ostream OS(SS);
209-
printValueDeclUSR(D, OS);
210-
usr = stringStorage->copyString(SS.str());
208+
llvm::raw_svector_ostream usrOS(usr);
209+
printValueDeclUSR(D, usrOS);
210+
211+
llvm::raw_svector_ostream nameOS(displayName);
212+
index::printDisplayName(D, nameOS);
211213
}
212214

213215
RenameRangeCollector(RenameRangeCollector &&collector) = default;
@@ -228,7 +230,17 @@ class RenameRangeCollector : public IndexDataConsumer {
228230
bool finishDependency(bool isClangModule) override { return true; }
229231

230232
Action startSourceEntity(const IndexSymbol &symbol) override {
231-
if (symbol.USR != usr) {
233+
// We need to check both the USR and the display name because multiple
234+
// distinct decls might have the same USR. For example, the following
235+
// declarations have the same USR with a single ERROR_TYPE parameter despite
236+
// being distinct declarations.
237+
//
238+
// func bar(body: Invalid) {}
239+
// func bar(ignoreCase: Bool, body: Invalid) {}
240+
//
241+
// The display name contains the argument labels, which is sufficient to
242+
// distinguish these declarations.
243+
if (symbol.USR != usr || symbol.name != displayName) {
232244
return IndexDataConsumer::Continue;
233245
}
234246
auto loc = indexSymbolToRenameLoc(symbol);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct Foo {
2+
func bar(body: Invalid) {}
3+
4+
// RUN: %sourcekitd-test -req=related-idents -pos=%(line + 1):8 %s -- %s
5+
func bar(ignoreCase: Bool, body: Invalid) {}
6+
}

0 commit comments

Comments
 (0)