Skip to content

Commit 615f686

Browse files
committed
Sema: Fix logic error in sanitizeProtocolRequirements()
If P is our protocol and it has an associated type A, we can't just fold any dependent member type T.[Q]A to T.[P]A; this only makes sense if T conforms to P. Fixes rdar://problem/122587920.
1 parent 8acd573 commit 615f686

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,15 +2516,15 @@ static void sanitizeProtocolRequirements(
25162516
sanitizeType = [&](Type outerType) {
25172517
return outerType.transformRec([&](TypeBase *type) -> llvm::Optional<Type> {
25182518
if (auto depMemTy = dyn_cast<DependentMemberType>(type)) {
2519-
if (!depMemTy->getAssocType() ||
2520-
depMemTy->getAssocType()->getProtocol() != proto) {
2519+
if ((!depMemTy->getAssocType() ||
2520+
depMemTy->getAssocType()->getProtocol() != proto) &&
2521+
proto->getGenericSignature()->requiresProtocol(depMemTy->getBase(), proto)) {
25212522

25222523
if (auto *assocType = proto->getAssociatedType(depMemTy->getName())) {
25232524
Type sanitizedBase = sanitizeType(depMemTy->getBase());
25242525
if (!sanitizedBase)
25252526
return Type();
2526-
return Type(DependentMemberType::get(sanitizedBase,
2527-
assocType));
2527+
return Type(DependentMemberType::get(sanitizedBase, assocType));
25282528
}
25292529

25302530
if (depMemTy->getBase()->is<GenericTypeParamType>())
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
2+
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
3+
4+
struct S<Element> {}
5+
6+
extension S: Sequence, IteratorProtocol {
7+
mutating func next() -> Element?? {
8+
fatalError()
9+
}
10+
}
11+
12+
extension S: Collection {
13+
var startIndex: Int {
14+
fatalError()
15+
}
16+
17+
var endIndex: Int {
18+
fatalError()
19+
}
20+
21+
subscript(_ index: Int) -> Element? {
22+
fatalError()
23+
}
24+
25+
func index(after index: Int) -> Int {
26+
fatalError()
27+
}
28+
}
29+
30+
let x: S<Int>.Type = S<Int>.Iterator.self

0 commit comments

Comments
 (0)