Skip to content

Commit 0b2e168

Browse files
committed
Sema: Tweak abstract witness inference priority again
We used to do attempt things in this order: - abstract witnesses, defaults, generic parameters I tried this but it broke things: - generic parameters, abstract witnesses, defaults Hoping this sticks: - abstract witnesses, generic parameters, defaults Fixes rdar://123262178.
1 parent 4f61ec3 commit 0b2e168

File tree

4 files changed

+47
-28
lines changed

4 files changed

+47
-28
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,7 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
23892389
// any fix this associated type to a concrete type.
23902390
for (auto conformance : getPeerConformances(conformance)) {
23912391
auto *conformedProto = conformance->getProtocol();
2392+
23922393
auto sig = conformedProto->getGenericSignature();
23932394

23942395
// FIXME: The RequirementMachine will assert on re-entrant construction.
@@ -2704,35 +2705,40 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
27042705
if (system.hasResolvedTypeWitness(assocType->getName()))
27052706
continue;
27062707

2707-
// If we find a default type definition, feed it to the system.
2708-
if (const auto &typeWitness = computeDefaultTypeWitness(assocType)) {
2709-
bool preferred = (typeWitness->getDefaultedAssocType()->getDeclContext()
2710-
== conformance->getProtocol());
2711-
system.addDefaultTypeWitness(typeWitness->getType(),
2712-
typeWitness->getDefaultedAssocType(),
2713-
preferred);
2714-
} else {
2715-
// As a last resort, look for a generic parameter that matches the name
2716-
// of the associated type.
2717-
if (auto genericSig = dc->getGenericSignatureOfContext()) {
2718-
// Ignore the generic parameters for AsyncIteratorProtocol.Failure and
2719-
// AsyncSequence.Failure.
2720-
if (!isAsyncIteratorProtocolFailure(assocType)) {
2721-
for (auto *gp : genericSig.getInnermostGenericParams()) {
2722-
// Packs cannot witness associated type requirements.
2723-
if (gp->isParameterPack())
2724-
continue;
2708+
bool found = false;
27252709

2726-
if (gp->getName() == assocType->getName()) {
2727-
system.addTypeWitness(assocType->getName(),
2728-
dc->mapTypeIntoContext(gp),
2729-
/*preferred=*/true);
2730-
}
2710+
// Look for a generic parameter that matches the name of the
2711+
// associated type.
2712+
if (auto genericSig = dc->getGenericSignatureOfContext()) {
2713+
// Ignore the generic parameters for AsyncIteratorProtocol.Failure and
2714+
// AsyncSequence.Failure.
2715+
if (!isAsyncIteratorProtocolFailure(assocType)) {
2716+
for (auto *gp : genericSig.getInnermostGenericParams()) {
2717+
// Packs cannot witness associated type requirements.
2718+
if (gp->isParameterPack())
2719+
continue;
2720+
2721+
if (gp->getName() == assocType->getName()) {
2722+
system.addTypeWitness(assocType->getName(),
2723+
dc->mapTypeIntoContext(gp),
2724+
/*preferred=*/true);
2725+
found = true;
2726+
break;
27312727
}
27322728
}
27332729
}
27342730
}
27352731

2732+
if (!found) {
2733+
// If we find a default type definition, feed it to the system.
2734+
if (const auto &typeWitness = computeDefaultTypeWitness(assocType)) {
2735+
bool preferred = (typeWitness->getDefaultedAssocType()->getDeclContext()
2736+
== conformance->getProtocol());
2737+
system.addDefaultTypeWitness(typeWitness->getType(),
2738+
typeWitness->getDefaultedAssocType(),
2739+
preferred);
2740+
}
2741+
}
27362742
}
27372743
}
27382744

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
2-
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
2+
// RUN: not %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-
// This is unfortunate but it is the behavior of Swift 5.10.
11-
let x: Int.Type = S<String>.A.self
10+
let x: String.Type = S<String>.A.self

test/decl/protocol/req/associated_type_inference_fixed_type_experimental_inference.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ do {
212212
// CHECK-NEXT: }
213213
struct Conformer1: P17a {} // expected-error {{type 'Conformer1' does not conform to protocol 'P17a'}}
214214
// CHECK-LABEL: Abstract type witness system for conformance of Conformer2<A> to P17b: {
215-
// CHECK-NEXT: A => (unresolved), [[EQUIV_CLASS:0x[0-9a-f]+]]
215+
// CHECK-NEXT: A => A (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
216216
// CHECK-NEXT: B => (unresolved)
217217
// CHECK-NEXT: }
218218
struct Conformer2<A>: P17b {} // expected-error {{type 'Conformer2<A>' does not conform to protocol 'P17b'}}
@@ -221,7 +221,7 @@ do {
221221
// CHECK-NEXT: }
222222
struct Conformer3: P17c {}
223223
// CHECK-LABEL: Abstract type witness system for conformance of Conformer4<A> to P17d: {
224-
// CHECK-NEXT: A => Int (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
224+
// CHECK-NEXT: A => A (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
225225
// CHECK-NEXT: B => Int (preferred), [[EQUIV_CLASS:0x[0-9a-f]+]]
226226
// CHECK-NEXT: }
227227
struct Conformer4<A>: P17d {}
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 protocol P {
5+
associatedtype A = Never
6+
}
7+
8+
public struct G<A>: P {}
9+
10+
public struct ConcreteA {}
11+
12+
public protocol Q: P where Self.A == ConcreteA {}
13+
14+
extension G: Q where A == ConcreteA {}

0 commit comments

Comments
 (0)