Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/IDE/CodeCompletionResultType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
return USRBasedType::null(Arena);
}

// ParameterizedProtocolType should always be wrapped in ExistentialType and
// cannot be mangled on its own.
// But ParameterizedProtocolType can currently occur in 'typealias'
// declarations. rdar://99176683
// To avoid crashing in USR generation, simply return a null type until the
// underlying issue has been fixed.
if (Ty->is<ParameterizedProtocolType>()) {
return USRBasedType::null(Arena);
}

SmallString<32> USR;
llvm::raw_svector_ostream OS(USR);
printTypeUSR(Ty, OS);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %empty-directory(%t/split)
// RUN: %empty-directory(%t/build)
// RUN: %{python} %utils/split_file.py -o %t/split %s

// RUN: %target-swift-frontend -emit-module -o %t/build %t/split/pck.swift

// RUN: %target-swift-ide-test -code-completion -source-filename %t/split/test.swift -I %t/build -code-completion-token=COMPLETE | %FileCheck %s

// BEGIN pck.swift

public protocol Foo<Bar> {
associatedtype Bar
}

public typealias Problem = Foo<String>

public protocol EmptyProto {}
public typealias ConstrainedBar<T: EmptyProto> = Foo<T>

// BEGIN test.swift

import pck

#^COMPLETE^#

// CHECK: Begin completions
// CHECK-DAG: Decl[Protocol]/OtherModule[pck]/Flair[RareType]: Foo[#Foo#];
// CHECK-DAG: Decl[TypeAlias]/OtherModule[pck]: Problem[#Foo<String>#];
// CHECK-DAG: Decl[TypeAlias]/OtherModule[pck]: ConstrainedBar[#Foo<T>#];
// CHECK: End completions
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Testing that these requests don't crash

public protocol Foo<Bar> {
associatedtype Bar
}
// RUN: %sourcekitd-test -req=cursor -pos=%(line+1):11 %s -- %s
typealias Problem = Foo<String>

protocol EmptyProto {}
// RUN: %sourcekitd-test -req=cursor -pos=%(line+1):11 %s -- %s
typealias ConstrainedBar<T: EmptyProto> = Foo<T>
// RUN: %sourcekitd-test -req=cursor -pos=%(line+1):11 %s -- %s
typealias ConstrainedBarMetatype<T: P> = Foo<T>.Type
16 changes: 16 additions & 0 deletions tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,22 @@ fillSymbolInfo(CursorSymbolInfo &Symbol, const DeclInfo &DInfo,
}
Symbol.TypeName = copyAndClearString(Allocator, Buffer);

// ParameterizedProtocolType should always be wrapped in ExistentialType and
// cannot be mangled on its own.
// But ParameterizedProtocolType can currently occur in 'typealias'
// declarations. rdar://99176683
// To avoid crashing in USR generation, return an error for now.
if (auto Ty = DInfo.VD->getInterfaceType()) {
while (auto MetaTy = Ty->getAs<MetatypeType>()) {
Ty = MetaTy->getInstanceType();
}
if (Ty && Ty->getCanonicalType()->is<ParameterizedProtocolType>()) {
return llvm::createStringError(
llvm::inconvertibleErrorCode(),
"Cannot mangle USR for ParameterizedProtocolType without 'any'.");
}
}

SwiftLangSupport::printDeclTypeUSR(DInfo.VD, OS);
Symbol.TypeUSR = copyAndClearString(Allocator, Buffer);

Expand Down