Skip to content

Commit 1dd79ae

Browse files
committed
Sema: Don't resolve protocol typealiases to DependentMemberTypes
1 parent b32694e commit 1dd79ae

File tree

3 files changed

+27
-54
lines changed

3 files changed

+27
-54
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -406,22 +406,14 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
406406

407407
if (selfType->is<GenericTypeParamType>()) {
408408
if (typeDecl->getDeclContext()->getSelfProtocolDecl()) {
409-
if (isa<AssociatedTypeDecl>(typeDecl) ||
410-
(isa<TypeAliasDecl>(typeDecl) &&
411-
!cast<TypeAliasDecl>(typeDecl)->isGeneric())) {
412-
// FIXME: We should use this lookup method for the Interface
413-
// stage too, but right now that causes problems with
414-
// Sequence.SubSequence vs Collection.SubSequence; the former
415-
// is more canonical, but if we return that instead of the
416-
// latter, we infer the wrong associated type in some cases,
417-
// because we use the Sequence.SubSequence default instead of
418-
// the Collection.SubSequence default, even when the conforming
419-
// type wants to conform to Collection.
420-
if (getStage() == TypeResolutionStage::Structural) {
421-
return DependentMemberType::get(selfType, typeDecl->getName());
422-
} else if (auto assocType = dyn_cast<AssociatedTypeDecl>(typeDecl)) {
423-
typeDecl = assocType->getAssociatedTypeAnchor();
424-
}
409+
auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl);
410+
if (getStage() == TypeResolutionStage::Structural &&
411+
aliasDecl && !aliasDecl->isGeneric()) {
412+
return aliasDecl->getStructuralType();
413+
}
414+
415+
if (auto assocType = dyn_cast<AssociatedTypeDecl>(typeDecl)) {
416+
typeDecl = assocType->getAssociatedTypeAnchor();
425417
}
426418
}
427419

@@ -2438,14 +2430,7 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
24382430
// context, and then set isNoEscape if @escaping is not present.
24392431
if (!ty) ty = resolveType(repr, instanceOptions);
24402432
if (!ty || ty->hasError()) return ty;
2441-
2442-
// Type aliases inside protocols are not yet resolved in the structural
2443-
// stage of type resolution
2444-
if (ty->is<DependentMemberType>() &&
2445-
resolution.getStage() == TypeResolutionStage::Structural) {
2446-
return ty;
2447-
}
2448-
2433+
24492434
// Handle @escaping
24502435
if (ty->is<FunctionType>()) {
24512436
if (attrs.has(TAK_escaping)) {
Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,27 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
// Reference to associated type from 'where' clause should not be
3+
// References to associated type from 'where' clause should be
44
// ambiguous when there's a typealias with the same name in another
5-
// protocol.
6-
//
7-
// FIXME: The semantics here are still really iffy. There's also a
8-
// case to be made that type aliases in protocol extensions should
9-
// only act as defaults and not as same-type constraints. However,
10-
// if we decide to go down that route, it's important that *both*
11-
// the unqualified (T) and qualified (Self.T) lookups behave the
12-
// same.
5+
// unrelated protocol.
6+
137
protocol P1 {
14-
typealias T = Int // expected-note {{found this candidate}}
8+
typealias T = Int // expected-note 3{{found this candidate}}
159
}
1610

1711
protocol P2 {
18-
associatedtype T // expected-note {{found this candidate}}
12+
associatedtype T // expected-note 3{{found this candidate}}
1913
}
2014

21-
// FIXME: This extension's generic signature is still minimized differently from
22-
// the next one. We need to decide if 'T == Int' is a redundant requirement or
23-
// not.
24-
extension P1 where Self : P2, T == Int {
25-
func takeT1(_: T) {}
26-
func takeT2(_: Self.T) {}
15+
extension P1 where Self : P2, T == Int { // expected-error {{'T' is ambiguous for type lookup in this context}}
16+
func takeT11(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
17+
func takeT12(_: Self.T) {}
2718
}
2819

2920
extension P1 where Self : P2 {
3021
// FIXME: This doesn't make sense -- either both should
3122
// succeed, or both should be ambiguous.
32-
func takeT1(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
33-
func takeT2(_: Self.T) {}
23+
func takeT21(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
24+
func takeT22(_: Self.T) {}
3425
}
3526

3627
// Same as above, but now we have two visible associated types with the same
@@ -39,20 +30,17 @@ protocol P3 {
3930
associatedtype T
4031
}
4132

42-
// FIXME: This extension's generic signature is still minimized differently from
43-
// the next one. We need to decide if 'T == Int' is a redundant requirement or
44-
// not.
4533
extension P2 where Self : P3, T == Int {
46-
func takeT1(_: T) {}
47-
func takeT2(_: Self.T) {}
34+
func takeT31(_: T) {}
35+
func takeT32(_: Self.T) {}
4836
}
4937

5038
extension P2 where Self : P3 {
51-
func takeT1(_: T) {}
52-
func takeT2(_: Self.T) {}
39+
func takeT41(_: T) {}
40+
func takeT42(_: Self.T) {}
5341
}
5442

5543
protocol P4 : P2, P3 {
56-
func takeT1(_: T)
57-
func takeT2(_: Self.T)
44+
func takeT51(_: T)
45+
func takeT52(_: Self.T)
5846
}

test/decl/typealias/protocol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ extension P10 {
268268
typealias U = Float
269269
}
270270

271-
extension P10 where T == Int { } // expected-warning{{neither type in same-type constraint ('Self.T' (aka 'Int') or 'Int') refers to a generic parameter or associated type}}
271+
extension P10 where T == Int { } // expected-warning{{neither type in same-type constraint ('Int' or 'Int') refers to a generic parameter or associated type}}
272272

273273
extension P10 where A == X<T> { }
274274

@@ -277,7 +277,7 @@ extension P10 where A == X<U> { }
277277
extension P10 where A == X<Self.U> { }
278278

279279
extension P10 where V == Int { } // expected-warning {{'V' is deprecated: just use Int, silly}}
280-
// expected-warning@-1{{neither type in same-type constraint ('Self.V' (aka 'Int') or 'Int') refers to a generic parameter or associated type}}
280+
// expected-warning@-1{{neither type in same-type constraint ('Int' or 'Int') refers to a generic parameter or associated type}}
281281

282282
// rdar://problem/36003312
283283
protocol P11 {

0 commit comments

Comments
 (0)