Skip to content

Commit d77e559

Browse files
committed
[GSB] Consistently use nested type name match constraints.
We generated a mix of "inferred" and "nested type name match" constraints for the case where we had two nested types with the same name and inferred that they are equal. Make them consistent by always using nested type name match constraints. This fixes a bug where we would get different canonical generic signatures in different source files because we inferred the same-type constraint with different requirement sources. Fixes rdar://problem/48049725. (cherry picked from commit af335c6)
1 parent a34907f commit d77e559

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,9 @@ TypeDecl *EquivalenceClass::lookupNestedType(
21002100
// Infer same-type constraints among same-named associated type anchors.
21012101
if (assocTypeAnchors.size() > 1) {
21022102
auto anchorType = getAnchor(builder, builder.getGenericParams());
2103-
auto inferredSource = FloatingRequirementSource::forInferred(nullptr);
2103+
auto inferredSource =
2104+
FloatingRequirementSource::forNestedTypeNameMatch(
2105+
assocTypeAnchors.front()->getName());
21042106
for (auto assocType : assocTypeAnchors) {
21052107
if (assocType == bestAssocType) continue;
21062108

@@ -4732,7 +4734,8 @@ void GenericSignatureBuilder::addedNestedType(PotentialArchetype *nestedPA) {
47324734
if (allNested.size() > 1) {
47334735
auto firstPA = allNested.front();
47344736
auto inferredSource =
4735-
FloatingRequirementSource::forInferred(nullptr);
4737+
FloatingRequirementSource::forNestedTypeNameMatch(
4738+
nestedPA->getNestedName());
47364739

47374740
addSameTypeRequirement(firstPA, nestedPA, inferredSource,
47384741
UnresolvedHandlingKind::GenerateConstraints);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
public protocol P1 {
2+
associatedtype A1: SomeClass
3+
}
4+
5+
public protocol P4: P2 where A2: P1 {}
6+
7+
8+
public class SomeClass { }
9+
10+
protocol P5 {
11+
associatedtype A3: P4
12+
}
13+
14+
struct Foo {
15+
static func f<T: P5>(_: T) {
16+
}
17+
}

test/Generics/rdar48049725.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir %S/Inputs/rdar48049725_other.swift | %FileCheck %s
2+
public protocol P3 {
3+
associatedtype A1: SomeClass
4+
}
5+
6+
7+
public protocol P2 {
8+
associatedtype A2: P3
9+
}
10+
11+
12+
func test<T: P5>(value: T) {
13+
// Ensure that we get the right generic signature for Foo.f
14+
// CHECK: call swiftcc void @"$s12rdar480497253FooV1fyyxAA2P5RzlFZ"
15+
Foo.f(value)
16+
}

test/Generics/requirement_inference.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,11 @@ protocol P10 {
154154
}
155155

156156
// CHECK-LABEL: sameTypeConcrete1@
157-
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int>
157+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int>
158158
func sameTypeConcrete1<T : P9 & P10>(_: T) where T.A == X3, T.C == T.B, T.C == Int { }
159159

160160
// CHECK-LABEL: sameTypeConcrete2@
161161
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.B == X3, τ_0_0.C == X3>
162-
// FIXME: Should have τ_0_0.A == τ_0_0.A
163162
func sameTypeConcrete2<T : P9 & P10>(_: T) where T.B : X3, T.C == T.B, T.C == X3 { }
164163
// expected-warning@-1{{redundant superclass constraint 'T.B' : 'X3'}}
165164
// expected-note@-2{{same-type constraint 'T.C' == 'X3' written here}}
@@ -402,7 +401,7 @@ protocol P30 {
402401
protocol P31 { }
403402

404403
// CHECK-LABEL: .sameTypeNameMatch1@
405-
// CHECK: Generic signature: <T where T : P29, T : P30, T.X : P31, T.X == T.X>
404+
// CHECK: Generic signature: <T where T : P29, T : P30, T.X : P31>
406405
func sameTypeNameMatch1<T: P29 & P30>(_: T) where T.X: P31 { }
407406

408407
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)