Skip to content

Commit d26ece7

Browse files
authored
Merge pull request #7957 from DougGregor/prefer-shorter-requirement-sources
2 parents fa4a196 + 58f7944 commit d26ece7

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,13 +493,30 @@ SourceLoc RequirementSource::getLoc() const {
493493
return SourceLoc();
494494
}
495495

496+
/// Compute the path length of a requirement source, counting only the number
497+
/// of \c ProtocolRequirement elements.
498+
static unsigned sourcePathLength(const RequirementSource *source) {
499+
unsigned count = 0;
500+
for (; source; source = source->parent) {
501+
if (source->kind == RequirementSource::ProtocolRequirement)
502+
++count;
503+
}
504+
return count;
505+
}
506+
496507
int RequirementSource::compare(const RequirementSource *other) const {
497508
// Prefer the derived option, if there is one.
498509
bool thisIsDerived = this->isDerivedRequirement();
499510
bool otherIsDerived = other->isDerivedRequirement();
500511
if (thisIsDerived != otherIsDerived)
501512
return thisIsDerived ? -1 : +1;
502513

514+
// Prefer the shorter path.
515+
unsigned thisLength = sourcePathLength(this);
516+
unsigned otherLength = sourcePathLength(other);
517+
if (thisLength != otherLength)
518+
return thisLength < otherLength ? -1 : +1;
519+
503520
// FIXME: Arbitrary hack to allow later requirement sources to stomp on
504521
// earlier ones. We need a proper ordering here.
505522
return +1;

test/Generics/conformance_access_path.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -typecheck %s -verify
2-
// RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1
1+
// RUN: %target-typecheck-verify-swift -typecheck -swift-version 4 %s -verify
2+
// RUN: %target-typecheck-verify-swift -typecheck -swift-version 4 -debug-generic-signatures %s > %t.dump 2>&1
33
// RUN: %FileCheck %s < %t.dump
44

55
protocol P0 { }
@@ -25,7 +25,12 @@ protocol P3 {
2525

2626
protocol P4: P3 { }
2727

28+
protocol P5 : P4 {
29+
associatedtype AssocP5 where AssocP3: Q0
30+
}
31+
2832
func acceptP0<T: P0>(_: T) { }
33+
func acceptQ0<T: Q0>(_: T) { }
2934
func acceptP1<T: P1>(_: T) { }
3035
func acceptP2<T: P2>(_: T) { }
3136
func acceptP3<T: P3>(_: T) { }
@@ -42,3 +47,11 @@ func testPaths2<U: P2 & P4>(_ t: U) where U.AssocP3 == U.AssocP2.AssocP1 {
4247
// CHECK: Conformance access path for U.AssocP3: P0 is U: P4 -> τ_0_0: P3 -> τ_0_0.AssocP3: P0
4348
acceptP0(t.getAssocP2().getAssocP1())
4449
}
50+
51+
func testPaths3<V: P5>(_ v: V) {
52+
// CHECK: Conformance access path for V.AssocP3: P0 is V: P5 -> τ_0_0.AssocP3: Q0 -> τ_0_0: P0
53+
acceptP0(v.getAssocP3())
54+
55+
// CHECK: Conformance access path for V.AssocP3: Q0 is V: P5 -> τ_0_0.AssocP3: Q0
56+
acceptQ0(v.getAssocP3())
57+
}

test/Generics/requirement_inference.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct Model_P3_P4_Eq<T : P3, U : P4> where T.P3Assoc == U.P4Assoc {}
117117
// CHECK-NEXT: Requirements:
118118
// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Inferred @ {{.*}}:32]
119119
// CHECK-NEXT: τ_0_1 : P4 [τ_0_1: Inferred @ {{.*}}:32]
120-
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self in P2)]
120+
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_1: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P4Assoc in P4)
121121
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3)]
122122
// FIXME: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0: Inferred]
123123
func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
@@ -126,7 +126,7 @@ func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
126126
// CHECK-NEXT: Requirements:
127127
// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Explicit @ {{.*}}:25]
128128
// CHECK-NEXT: τ_0_1 : P4 [τ_0_1: Explicit @ {{.*}}:33]
129-
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self in P2)]
129+
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_1: Explicit @ {{.*}}:33 -> Protocol requirement (via Self.P4Assoc in P4)
130130
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3)]
131131
// CHECK-NEXT: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0[.P3].P3Assoc: Explicit]
132132
func inferSameType2<T : P3, U : P4>(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {}

0 commit comments

Comments
 (0)