Skip to content

Commit d8b5b88

Browse files
authored
Merge pull request #71548 from slavapestov/assoc-type-regression-fixes-3
Sema: Restore old behavior of generic parameters with associated type inference
2 parents c03b9c2 + f95109d commit d8b5b88

5 files changed

+44
-29
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2440,29 +2440,6 @@ AssociatedTypeInference::computeAbstractTypeWitness(
24402440
void AssociatedTypeInference::collectAbstractTypeWitnesses(
24412441
TypeWitnessSystem &system,
24422442
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
2443-
// Look for suitably-named generic parameters first, before we go digging
2444-
// through same-type requirements of protocols.
2445-
if (auto genericSig = dc->getGenericSignatureOfContext()) {
2446-
for (auto *const assocType : unresolvedAssocTypes) {
2447-
// Ignore the generic parameters for AsyncIteratorProtocol.Failure and
2448-
// AsyncSequence.Failure.
2449-
if (isAsyncIteratorProtocolFailure(assocType))
2450-
continue;
2451-
2452-
for (auto *gp : genericSig.getInnermostGenericParams()) {
2453-
// Packs cannot witness associated type requirements.
2454-
if (gp->isParameterPack())
2455-
continue;
2456-
2457-
if (gp->getName() == assocType->getName()) {
2458-
system.addTypeWitness(assocType->getName(),
2459-
dc->mapTypeIntoContext(gp),
2460-
/*preferred=*/true);
2461-
}
2462-
}
2463-
}
2464-
}
2465-
24662443
auto considerProtocolRequirements = [&](ProtocolDecl *conformedProto) {
24672444
// FIXME: The RequirementMachine will assert on re-entrant construction.
24682445
// We should find a more principled way of breaking this cycle.
@@ -2515,7 +2492,28 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
25152492
system.addDefaultTypeWitness(typeWitness->getType(),
25162493
typeWitness->getDefaultedAssocType(),
25172494
preferred);
2495+
} else {
2496+
// As a last resort, look for a generic parameter that matches the name
2497+
// of the associated type.
2498+
if (auto genericSig = dc->getGenericSignatureOfContext()) {
2499+
// Ignore the generic parameters for AsyncIteratorProtocol.Failure and
2500+
// AsyncSequence.Failure.
2501+
if (!isAsyncIteratorProtocolFailure(assocType)) {
2502+
for (auto *gp : genericSig.getInnermostGenericParams()) {
2503+
// Packs cannot witness associated type requirements.
2504+
if (gp->isParameterPack())
2505+
continue;
2506+
2507+
if (gp->getName() == assocType->getName()) {
2508+
system.addTypeWitness(assocType->getName(),
2509+
dc->mapTypeIntoContext(gp),
2510+
/*preferred=*/true);
2511+
}
2512+
}
2513+
}
2514+
}
25182515
}
2516+
25192517
}
25202518
}
25212519

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
2-
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
2+
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
33

44
protocol P {
55
associatedtype A = Int
66
}
77

88
struct S<A>: P {}
99

10-
let x: String.Type = S<String>.A.self
10+
// This is unfortunate but it is the behavior of Swift 5.10.
11+
let x: Int.Type = S<String>.A.self

test/decl/protocol/req/associated_type_inference_fixed_type_experimental_inference.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ do {
214214
// CHECK-NEXT: }
215215
struct Conformer1: P17a {} // expected-error {{type 'Conformer1' does not conform to protocol 'P17a'}}
216216
// CHECK-LABEL: Abstract type witness system for conformance of Conformer2<A> to P17b: {
217-
// CHECK-NEXT: A => A (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
217+
// CHECK-NEXT: A => (unresolved), [[EQUIV_CLASS:0x[0-9a-f]+]]
218218
// CHECK-NEXT: B => (unresolved)
219219
// CHECK-NEXT: }
220220
struct Conformer2<A>: P17b {} // expected-error {{type 'Conformer2<A>' does not conform to protocol 'P17b'}}
@@ -223,7 +223,7 @@ do {
223223
// CHECK-NEXT: }
224224
struct Conformer3: P17c {}
225225
// CHECK-LABEL: Abstract type witness system for conformance of Conformer4<A> to P17d: {
226-
// CHECK-NEXT: A => A (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
226+
// CHECK-NEXT: A => Int (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
227227
// CHECK-NEXT: B => Int (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
228228
// CHECK-NEXT: }
229229
struct Conformer4<A>: P17d {}
@@ -645,7 +645,7 @@ protocol P37b {
645645
}
646646
do {
647647
// CHECK-LABEL: Abstract type witness system for conformance of Conformer1<C> to P37b: {
648-
// CHECK-NEXT: C => C (preferred),
648+
// CHECK-NEXT: C => Self.B.A (preferred),
649649
// CHECK-NEXT: }
650650
struct Conformer1<C>: P37b {
651651
struct Inner: P37a { typealias A = C }

test/decl/protocol/req/associated_type_inference_stdlib_3.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
1+
// RUN: not %target-typecheck-verify-swift -enable-experimental-associated-type-inference
22
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
33

4+
// FIXME: Get this passing with -enable-experimental-associated-type-inference again.
5+
46
struct FooIterator<T: Sequence>: IteratorProtocol {
57
typealias Element = T.Element
68

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
2+
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
3+
4+
public struct S<Element: Hashable> {
5+
public typealias A = [Element: Int]
6+
}
7+
8+
extension S: Sequence {
9+
public func makeIterator() -> A.Iterator {
10+
fatalError()
11+
}
12+
}
13+
14+
let x: (key: String, value: Int).Type = S<String>.Element.self

0 commit comments

Comments
 (0)