Skip to content

Commit e471e40

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.
1 parent 24aa030 commit e471e40

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
@@ -1795,8 +1795,8 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
17951795

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

@@ -2750,6 +2750,16 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
27502750
}
27512751
}
27522752

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