Skip to content

Commit f136b88

Browse files
committed
[Associated type inference] Don’t get blocked by typealiases in protocol extensions.
Typealiases in protocol extensions can be used to satisfy associated type requirements. However, when they don’t meet all of the requirements placed on the associated type, fall back to the normal inference path rather than failing outright. Fixes SR-6609 / rdar://problem/36038033. (cherry picked from commit e471e40)
1 parent e40c8f6 commit f136b88

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,8 +1796,8 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
17961796

17971797
// If we already recoded this type witness, there's nothing to do.
17981798
if (Conformance->hasTypeWitness(assocType)) {
1799-
assert(Conformance->getTypeWitness(assocType, nullptr)
1800-
->isEqual(type) && "Conflicting type witness deductions");
1799+
assert(Conformance->getTypeWitness(assocType, nullptr)->isEqual(type) &&
1800+
"Conflicting type witness deductions");
18011801
return;
18021802
}
18031803

@@ -2751,6 +2751,16 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
27512751
}
27522752
}
27532753

2754+
// If there are no viable witnesses, and all nonviable candidates came from
2755+
// protocol extensions, treat this as "missing".
2756+
if (viable.empty() &&
2757+
std::find_if(nonViable.begin(), nonViable.end(),
2758+
[](const std::pair<TypeDecl *, CheckTypeWitnessResult> &x) {
2759+
return x.first->getDeclContext()
2760+
->getAsProtocolOrProtocolExtensionContext() == nullptr;
2761+
}) == nonViable.end())
2762+
return ResolveWitnessResult::Missing;
2763+
27542764
// If there is a single viable candidate, form a substitution for it.
27552765
if (viable.size() == 1) {
27562766
auto interfaceType = viable.front().second;

test/decl/protocol/req/associated_type_inference.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,19 @@ protocol P17 {
469469
protocol Q17 : P17 where T == Int { }
470470

471471
struct S17 : Q17 { }
472+
473+
// Typealiases from protocol extensions should not inhibit associated type
474+
// inference.
475+
protocol P18 {
476+
associatedtype A
477+
}
478+
479+
protocol P19 : P18 {
480+
associatedtype B
481+
}
482+
483+
extension P18 where Self: P19 {
484+
typealias A = B
485+
}
486+
487+
struct X18<A> : P18 { }

0 commit comments

Comments
 (0)