Skip to content

Commit 970f441

Browse files
authored
Merge pull request #38228 from ahoppen/pr-5.5/suggest-typealias-on-protocols
[5.5][CodeCompletion] Suggest typealias on protocols
2 parents bbb018b + b4c9bca commit 970f441

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

lib/Sema/IDETypeCheckingRequests.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ static bool isMemberDeclAppliedInternal(const DeclContext *DC, Type BaseTy,
148148
BaseTy->hasUnresolvedType() || BaseTy->hasError())
149149
return true;
150150

151+
if (isa<TypeAliasDecl>(VD) && BaseTy->is<ProtocolType>()) {
152+
// The protocol doesn't satisfy its own generic signature (static members
153+
// of the protocol are not visible on the protocol itself) but we can still
154+
// access typealias declarations on it.
155+
return true;
156+
}
157+
151158
const GenericContext *genericDecl = VD->getAsGenericContext();
152159
if (!genericDecl)
153160
return true;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t
3+
4+
protocol MyProto {
5+
typealias Content = Int
6+
}
7+
func testSimpleInTypeCompletion() -> MyProto.#^SIMPLE_IN_TYPE_COMPLETION^# {}
8+
// SIMPLE_IN_TYPE_COMPLETION: Begin completions, 3 items
9+
// SIMPLE_IN_TYPE_COMPLETION-DAG: Decl[TypeAlias]/CurrNominal: Content[#Int#];
10+
// SIMPLE_IN_TYPE_COMPLETION-DAG: Keyword/None: Protocol[#MyProto.Protocol#];
11+
// SIMPLE_IN_TYPE_COMPLETION-DAG: Keyword/None: Type[#MyProto.Type#];
12+
// SIMPLE_IN_TYPE_COMPLETION: End completions
13+
14+
func testUnconstrainedUnresolvedMember() {
15+
let _: MyProto = .#^UNCONSTRAINED_UNRESOLVED_MEMBER^#
16+
// UNCONSTRAINED_UNRESOLVED_MEMBER: Begin completions, 1 item
17+
// UNCONSTRAINED_UNRESOLVED_MEMBER-DAG: Decl[TypeAlias]/CurrNominal: Content[#Int#];
18+
// UNCONSTRAINED_UNRESOLVED_MEMBER: End completions
19+
}
20+
21+
protocol MyOtherProto {
22+
associatedtype MyAssocType
23+
}
24+
extension MyOtherProto where MyAssocType == String {
25+
typealias Content = Int
26+
}
27+
28+
// `Content` is actually accessible on `MyOtherProto` here, but that seems more like a bug of the language than a feature, so we don't want to promote it in code completion.
29+
func testConstrainedInTypeCompletion() -> MyOtherProto.#^CONSTRAINED_IN_TYPE_COMPLETION^# {}
30+
// CONSTRAINED_IN_TYPE_COMPLETION: Begin completions, 3 items
31+
// CONSTRAINED_IN_TYPE_COMPLETION-DAG: Decl[AssociatedType]/CurrNominal: MyAssocType;
32+
// CONSTRAINED_IN_TYPE_COMPLETION-DAG: Keyword/None: Protocol[#MyOtherProto.Protocol#];
33+
// CONSTRAINED_IN_TYPE_COMPLETION-DAG: Keyword/None: Type[#MyOtherProto.Type#];
34+
// CONSTRAINED_IN_TYPE_COMPLETION: End completions
35+
36+
func testConstrainedUnresolvedMember() {
37+
let _: MyOtherProto = .#^CONSTRAINED_UNRESOLVED_MEMBER^#
38+
// CONSTRAINED_UNRESOLVED_MEMBER: Begin completions, 1 item
39+
// CONSTRAINED_UNRESOLVED_MEMBER-DAG: Decl[AssociatedType]/CurrNominal: MyAssocType;
40+
// CONSTRAINED_UNRESOLVED_MEMBER: End completions
41+
}
42+
43+
protocol ProtoWithGenericTypealias {
44+
typealias Storage<T> = Array<T>
45+
}
46+
func testGenericInTypeCompletion() -> ProtoWithGenericTypealias.#^GENERIC_IN_TYPE_COMPLETION^# {}
47+
// GENERIC_IN_TYPE_COMPLETION: Begin completions, 3 items
48+
// GENERIC_IN_TYPE_COMPLETION-DAG: Decl[TypeAlias]/CurrNominal: Storage[#Array<T>#];
49+
// GENERIC_IN_TYPE_COMPLETION-DAG: Keyword/None: Protocol[#ProtoWithGenericTypealias.Protocol#];
50+
// GENERIC_IN_TYPE_COMPLETION-DAG: Keyword/None: Type[#ProtoWithGenericTypealias.Type#];
51+
// GENERIC_IN_TYPE_COMPLETION: End completions
52+
53+
func testGenericUnresolvedMember() {
54+
let _: ProtoWithGenericTypealias = .#^GENERIC_UNRESOLVED_MEMBER^#
55+
// GENERIC_UNRESOLVED_MEMBER: Begin completions, 1 item
56+
// GENERIC_UNRESOLVED_MEMBER-DAG: Decl[TypeAlias]/CurrNominal: Storage[#Array<T>#];
57+
// GENERIC_UNRESOLVED_MEMBER: End completions
58+
}

test/IDE/complete_unresolved_members.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,10 @@ func testSubType() {
450450
func testMemberTypealias() {
451451
var _: MyProtocol = .#^SUBTYPE_2^#
452452
}
453-
// SUBTYPE_2-NOT: Begin completions
453+
// SUBTYPE_2: Begin completions, 2 items
454+
// SUBTYPE_2-DAG: Decl[TypeAlias]/CurrNominal/TypeRelation[Convertible]: Concrete1[#BaseClass#];
455+
// SUBTYPE_2-DAG: Decl[TypeAlias]/CurrNominal/TypeRelation[Convertible]: Concrete2[#AnotherTy#];
456+
// SUBTYPE_2: End completions
454457

455458
enum Generic<T> {
456459
case contains(content: T)

0 commit comments

Comments
 (0)