Skip to content

Commit 3282b86

Browse files
committed
AssociatedTypeInference: Fix regression introduced in 1cf9622
1 parent 3290833 commit 3282b86

File tree

3 files changed

+54
-9
lines changed

3 files changed

+54
-9
lines changed

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,9 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
11851185
for (const auto &witness : abstractTypeWitnesses) {
11861186
Type type = witness.getType();
11871187
if (type->hasTypeParameter()) {
1188-
if (witness.getKind() != AbstractTypeWitnessKind::GenericParam) {
1188+
if (witness.getKind() == AbstractTypeWitnessKind::GenericParam) {
1189+
type = type = dc->mapTypeIntoContext(type);
1190+
} else {
11891191
// Replace type parameters with other known or tentative type witnesses.
11901192
type = type.subst(
11911193
[&](SubstitutableType *type) {
@@ -1200,23 +1202,26 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
12001202
if (type->hasError())
12011203
return witness.getAssocType();
12021204

1203-
// FIXME: If we still have a type parameter and it isn't a generic
1204-
// parameter of the conforming nominal, it's either a cycle or a
1205-
// solution that is beyond the current algorithm, i.e.
1206-
//
1205+
// FIXME: If mapping into context yields an error, or we still have a
1206+
// type parameter despite not having a generic environment, then a type
1207+
// parameter was sent to a tentative type witness that itself is a type
1208+
// parameter, and the solution is cyclic, e.g. { A := B.A, B := A.B },
1209+
// or beyond the current algorithm, e.g.
12071210
// protocol P {
12081211
// associatedtype A = B
12091212
// associatedtype B = C
12101213
// associatedtype C = Int
12111214
// }
12121215
// struct Conformer: P {}
1213-
if (type->hasTypeParameter() &&
1214-
!adoptee->getAnyNominal()->isGeneric()) {
1216+
if (dc->getGenericEnvironmentOfContext()) {
1217+
type = dc->mapTypeIntoContext(type);
1218+
1219+
if (type->hasError())
1220+
return witness.getAssocType();
1221+
} else if (type->hasTypeParameter()) {
12151222
return witness.getAssocType();
12161223
}
12171224
}
1218-
1219-
type = dc->mapTypeIntoContext(type);
12201225
}
12211226

12221227
if (const auto &failed = checkTypeWitness(type, witness.getAssocType(),

test/decl/protocol/req/associated_type_inference_fixed_type.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,12 @@ protocol P13c: P13a, P13b where A == B {}
120120
struct S13: P13c { // OK, A == B == Never
121121
func foo(arg: Never) {}
122122
}
123+
124+
protocol P14 {
125+
associatedtype A = Array<Self>
126+
}
127+
do {
128+
struct Outer<Element> {
129+
struct Conformer: P14 {}
130+
}
131+
}

test/decl/protocol/req/sr15460.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
public protocol P {}
4+
5+
extension Array {
6+
public struct Inner {}
7+
}
8+
9+
extension Array.Inner:
10+
BidirectionalCollection,
11+
Collection,
12+
MutableCollection,
13+
RandomAccessCollection,
14+
Sequence
15+
where Element: P {
16+
public typealias Element = Array<Element>.Element
17+
public typealias Index = Array<Element>.Index
18+
public typealias Indices = Array<Element>.Indices
19+
public typealias SubSequence = Array<Element>.SubSequence
20+
21+
public subscript(position: Array<Element>.Index) -> Element {
22+
get {} set {}
23+
}
24+
25+
public subscript(bounds: Range<Array<Element>.Index>) -> SubSequence {
26+
get {} set {}
27+
}
28+
29+
public var startIndex: Index {0}
30+
public var endIndex: Index {0}
31+
}

0 commit comments

Comments
 (0)