Skip to content

Commit 41dde88

Browse files
committed
Sema: Allow unqualified type lookup to find typealiases in protocols
Not really specific to typealiases; but we don't allow nominal types to be nested inside protocols yet, and all other types of protocol members have witnesses in the concrete type. Fixes <https://bugs.swift.org/browse/SR-2792>.
1 parent 18adb53 commit 41dde88

File tree

5 files changed

+35
-14
lines changed

5 files changed

+35
-14
lines changed

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,38 @@ SmallVector<TypeDecl *, 1>
214214
TypeChecker::lookupUnqualifiedType(DeclContext *dc, DeclName name,
215215
SourceLoc loc,
216216
NameLookupOptions options) {
217+
SmallVector<TypeDecl *, 1> decls;
218+
219+
// Try lookup without ProtocolMembers first.
217220
UnqualifiedLookup lookup(
218221
name, dc, this,
219222
options.contains(NameLookupFlags::KnownPrivate),
220223
loc,
221224
/*OnlyTypes=*/true,
222-
options.contains(NameLookupFlags::ProtocolMembers),
225+
/*ProtocolMembers=*/false,
223226
options.contains(NameLookupFlags::IgnoreAccessibility));
224-
225-
LookupResult result;
226-
SmallVector<TypeDecl *, 1> decls;
227227
for (auto found : lookup.Results)
228228
decls.push_back(cast<TypeDecl>(found.getValueDecl()));
229+
230+
if (decls.empty() &&
231+
options.contains(NameLookupFlags::ProtocolMembers)) {
232+
// Try again, this time with protocol members.
233+
//
234+
// FIXME: Fix the problem where if NominalTypeDecl::getAllProtocols()
235+
// is called too early, we start resolving extensions -- even those
236+
// which do provide conformances.
237+
UnqualifiedLookup lookup(
238+
name, dc, this,
239+
options.contains(NameLookupFlags::KnownPrivate),
240+
loc,
241+
/*OnlyTypes=*/true,
242+
/*ProtocolMembers=*/true,
243+
options.contains(NameLookupFlags::IgnoreAccessibility));
244+
245+
for (auto found : lookup.Results)
246+
decls.push_back(cast<TypeDecl>(found.getValueDecl()));
247+
}
248+
229249
return decls;
230250
}
231251

lib/Sema/TypeCheckType.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,9 +1031,6 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
10311031
NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions;
10321032
if (options.contains(TR_KnownNonCascadingDependency))
10331033
lookupOptions |= NameLookupFlags::KnownPrivate;
1034-
// FIXME: Eliminate this once we can handle finding protocol members
1035-
// in resolveTypeInContext.
1036-
lookupOptions -= NameLookupFlags::ProtocolMembers;
10371034
auto globals = TC.lookupUnqualifiedType(lookupDC,
10381035
comp->getIdentifier(),
10391036
comp->getIdLoc(),

test/Generics/associated_types.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ struct Z : Fooable {
2121
var a : AssocType // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} {{9-10=_}}
2222
}
2323

24-
// FIXME: We should be able to find this.
25-
func blarg() -> AssocType {} // expected-error{{use of undeclared type 'AssocType'}}
24+
func blarg() -> AssocType {}
2625

2726
func wonka() -> Z.AssocType {}
2827
}

test/decl/ext/generic.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,9 @@ struct S4<Q>: P4 {
152152
}
153153

154154
extension S4 where T : P5 {}
155+
156+
struct S5<Q> {
157+
init(_: Q) { }
158+
}
159+
160+
extension S5 : P4 {}

test/decl/typealias/protocol.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ struct T5 : P5 {
154154
var v2: P5.T2 // expected-error {{typealias 'T2' can only be used with a concrete type or generic parameter base}}
155155
var v3: P5.X // expected-error {{typealias 'X' can only be used with a concrete type or generic parameter base}}
156156

157-
// FIXME: Unqualified reference to typealias from a protocol conformance
158-
var v4: T1 // expected-error {{use of undeclared type 'T1'}}
159-
var v5: T2 // expected-error {{use of undeclared type 'T2'}}
157+
// Unqualified reference to typealias from a protocol conformance
158+
var v4: T1 // OK
159+
var v5: T2 // OK
160160

161161
// Qualified reference
162162
var v6: T5.T1 // OK
@@ -178,8 +178,7 @@ extension P7 {
178178
struct S7 : P7 {
179179
typealias A = Int
180180

181-
// FIXME
182-
func inTypeContext(y: Y) // expected-error {{use of undeclared type 'Y'}}
181+
func inTypeContext(y: Y) { }
183182

184183
func inExpressionContext() {
185184
_ = Y.self

0 commit comments

Comments
 (0)