Skip to content

Commit 0aa15a8

Browse files
committed
[SourceKit] Workaround a bug that parameterized protocols without 'any' cannot be mangled
`typealias` is currently allowed to refer to a protocol without the `any` keyword. This breaks mangling the typealias type into a USR will crash because parameterized protocols are expected to be `any` types. Implement a SourceKit-specific minimal workaround for that problem by not computing USRs for parameterized protocols. rdar://98623438
1 parent fd4e98a commit 0aa15a8

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

lib/IDE/CodeCompletionResultType.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
195195
return USRBasedType::null(Arena);
196196
}
197197

198+
// ParameterizedProtocolType should always be wrapped in ExistentialType and
199+
// cannot be mangled on its own.
200+
// But ParameterizedProtocolType can currently occur in 'typealias'
201+
// declarations. rdar://99176683
202+
// To avoid crashing in USR generation, simply return a null type until the
203+
// underlying issue has been fixed.
204+
if (Ty->is<ParameterizedProtocolType>()) {
205+
return USRBasedType::null(Arena);
206+
}
207+
198208
SmallString<32> USR;
199209
llvm::raw_svector_ostream OS(USR);
200210
printTypeUSR(Ty, OS);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t/split)
2+
// RUN: %empty-directory(%t/build)
3+
// RUN: %{python} %utils/split_file.py -o %t/split %s
4+
5+
// RUN: %target-swift-frontend -emit-module -o %t/build %t/split/pck.swift
6+
7+
// RUN: %target-swift-ide-test -code-completion -source-filename %t/split/test.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s
8+
9+
// BEGIN pck.swift
10+
11+
public protocol Foo<Bar> {
12+
associatedtype Bar
13+
}
14+
15+
public typealias Problem = Foo<String>
16+
17+
// BEGIN test.swift
18+
19+
import pck
20+
21+
#^COMPLETE^#
22+
23+
// CHECK: Begin completions
24+
// CHECK-DAG: Decl[Protocol]/OtherModule[pck]/Flair[RareType]: Foo[#Foo#];
25+
// CHECK-DAG: Decl[TypeAlias]/OtherModule[pck]: Problem[#Foo<String>#];
26+
// CHECK: End completions
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %empty-directory(%t/split)
2+
// RUN: %empty-directory(%t/build)
3+
// RUN: %{python} %utils/split_file.py -o %t/split %s
4+
5+
// RUN: %target-swift-frontend -emit-module -o %t/build %t/split/pck.swift
6+
7+
// RUN: %sourcekitd-test -req=cursor -pos=4:8 %t/split/test.swift -- %t/split/test.swift -I %t/build | %FileCheck %s
8+
9+
10+
// BEGIN pck.swift
11+
12+
public protocol Foo<Bar> {
13+
associatedtype Bar
14+
}
15+
16+
public typealias Problem = Foo<String>
17+
18+
// BEGIN test.swift
19+
20+
import pck
21+
22+
let a: Problem
23+
24+
// CHECK: Cannot mangle USR for ParameterizedProtocolType without 'any'

tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,22 @@ fillSymbolInfo(CursorSymbolInfo &Symbol, const DeclInfo &DInfo,
948948
}
949949
Symbol.TypeName = copyAndClearString(Allocator, Buffer);
950950

951+
// ParameterizedProtocolType should always be wrapped in ExistentialType and
952+
// cannot be mangled on its own.
953+
// But ParameterizedProtocolType can currently occur in 'typealias'
954+
// declarations. rdar://99176683
955+
// To avoid crashing in USR generation, return an error for now.
956+
if (auto Ty = DInfo.VD->getInterfaceType()) {
957+
if (auto MetaTy = Ty->getAs<MetatypeType>()) {
958+
Ty = MetaTy->getInstanceType();
959+
}
960+
if (Ty && Ty->getCanonicalType()->is<ParameterizedProtocolType>()) {
961+
return llvm::createStringError(
962+
llvm::inconvertibleErrorCode(),
963+
"Cannot mangle USR for ParameterizedProtocolType without 'any'.");
964+
}
965+
}
966+
951967
SwiftLangSupport::printDeclTypeUSR(DInfo.VD, OS);
952968
Symbol.TypeUSR = copyAndClearString(Allocator, Buffer);
953969

0 commit comments

Comments
 (0)