Skip to content

Commit c725660

Browse files
committed
[GSB] When adding same-type requirements pick representative based on canonical order
Instead of trying to order based on the "nested depth", let's always prefer canonical ordering of type parameters when it comes to picking representative equivalence class. Resolves: rdar://problem/45957015
1 parent a820992 commit c725660

File tree

4 files changed

+26
-12
lines changed

4 files changed

+26
-12
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4889,15 +4889,12 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenTypeParameters(
48894889
auto T1 = OrigT1->getRepresentative();
48904890
auto T2 = OrigT2->getRepresentative();
48914891

4892-
// Decide which potential archetype is to be considered the representative.
4893-
// We prefer potential archetypes with lower nesting depths, because it
4894-
// prevents us from unnecessarily building deeply nested potential archetypes.
4895-
unsigned nestingDepth1 = T1->getNestingDepth();
4896-
unsigned nestingDepth2 = T2->getNestingDepth();
4897-
if (nestingDepth2 < nestingDepth1) {
4892+
// Pick representative based on the canonical ordering of the type parameters.
4893+
if (compareDependentTypes(depType2, depType1) < 0) {
48984894
std::swap(T1, T2);
48994895
std::swap(OrigT1, OrigT2);
49004896
std::swap(equivClass, equivClass2);
4897+
std::swap(depType1, depType2);
49014898
}
49024899

49034900
// T1 must have an equivalence class; create one if we don't already have

test/Generics/rdar45957015.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol C {
4+
associatedtype T : Collection where T.Element == Self
5+
}
6+
7+
protocol V : C, RawRepresentable where RawValue == String {}
8+
9+
protocol P {
10+
associatedtype A: V
11+
}
12+
13+
extension P {
14+
func foo<U: Collection>(_ args: U) -> String where U.Element == A {
15+
return args.reduce("", { $1.rawValue }) // Ok
16+
}
17+
}

test/Generics/same_type_constraints.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,11 @@ func intercomponentSameComponents<T: P10>(_: T)
351351
T.B == T.A { } // expected-note{{previous same-type constraint 'T.B' == 'T.A' written here}}
352352

353353
func intercomponentMoreThanSpanningTree<T: P10>(_: T)
354-
where T.A == T.B,
354+
where T.A == T.B, // expected-note {{previous same-type constraint 'T.A' == 'T.B' written here}}
355355
T.B == T.C,
356-
T.D == T.E, // expected-note{{previous same-type constraint 'T.D' == 'T.E' written here}}
356+
T.D == T.E, // expected-warning {{redundant same-type constraint 'T.D' == 'T.E'}}
357357
T.D == T.B,
358-
T.E == T.B // expected-warning{{redundant same-type constraint 'T.E' == 'T.B'}}
358+
T.E == T.B
359359
{ }
360360

361361
func trivialRedundancy<T: P10>(_: T) where T.A == T.A { } // expected-warning{{redundant same-type constraint 'T.A' == 'T.A'}}

test/decl/protocol/req/associated_type_ambiguity.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ protocol P1 {
1515
}
1616

1717
protocol P2 {
18-
associatedtype T // expected-note {{found this candidate}}
18+
associatedtype T // expected-note 2 {{found this candidate}}
1919
}
2020

2121
// FIXME: This extension's generic signature is still minimized differently from
@@ -36,7 +36,7 @@ extension P1 where Self : P2 {
3636
// Same as above, but now we have two visible associated types with the same
3737
// name.
3838
protocol P3 {
39-
associatedtype T
39+
associatedtype T // expected-note {{found this candidate}}
4040
}
4141

4242
// FIXME: This extension's generic signature is still minimized differently from
@@ -48,7 +48,7 @@ extension P2 where Self : P3, T == Int {
4848
}
4949

5050
extension P2 where Self : P3 {
51-
func takeT1(_: T) {}
51+
func takeT1(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
5252
func takeT2(_: Self.T) {}
5353
}
5454

0 commit comments

Comments
 (0)