Skip to content

Commit f4ff260

Browse files
committed
RequirementMachine: Subtle fix for minimal conformances algorithm
We don't need to be able to recover the parent type of a conformance rule if the rule itself is redundant.
1 parent 8a222b5 commit f4ff260

File tree

2 files changed

+65
-15
lines changed

2 files changed

+65
-15
lines changed

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -655,21 +655,21 @@ bool MinimalConformances::isValidConformancePath(
655655

656656
if (!foundValidConformancePath)
657657
return false;
658-
}
659-
660-
auto found = ParentPaths.find(ruleID);
661-
if (found != ParentPaths.end()) {
662-
SWIFT_DEFER {
663-
visited.erase(ruleID);
664-
};
665-
visited.insert(ruleID);
666-
667-
// If 'req' is based on some other conformance requirement
668-
// `T.[P.]A : Q', we want to make sure that we have a
669-
// non-redundant derivation for 'T : P'.
670-
if (!isValidConformancePath(visited, found->second,
671-
/*allowConcrete=*/false)) {
672-
return false;
658+
} else {
659+
auto found = ParentPaths.find(ruleID);
660+
if (found != ParentPaths.end()) {
661+
SWIFT_DEFER {
662+
visited.erase(ruleID);
663+
};
664+
visited.insert(ruleID);
665+
666+
// If 'req' is based on some other conformance requirement
667+
// `T.[P.]A : Q', we want to make sure that we have a
668+
// non-redundant derivation for 'T : P'.
669+
if (!isValidConformancePath(visited, found->second,
670+
/*allowConcrete=*/false)) {
671+
return false;
672+
}
673673
}
674674
}
675675
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
3+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P1@
4+
// CHECK-NEXT: Requirement signature: <Self>
5+
6+
protocol P1 {}
7+
8+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P2@
9+
// CHECK-NEXT: Requirement signature: <Self where Self.A : P1, Self.B : P2>
10+
11+
protocol P2 {
12+
associatedtype A: P1
13+
associatedtype B: P2
14+
}
15+
16+
struct Concrete: P1, P2 {
17+
typealias A = Concrete
18+
typealias B = Concrete
19+
}
20+
21+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P3a@
22+
// CHECK-NEXT: Requirement signature: <Self where Self.T : P2>
23+
24+
protocol P3a {
25+
associatedtype T : P2
26+
}
27+
28+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P3b@
29+
// CHECK-NEXT: Requirement signature: <Self where Self.T : P2, Self.T.A == Self.T.B>
30+
31+
protocol P3b {
32+
associatedtype T : P2 where T.A == T.B
33+
}
34+
35+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P4a@
36+
// CHECK-NEXT: Requirement signature: <Self where Self : P3a, Self.T == Concrete>
37+
38+
protocol P4a : P3a where T.A == T.B, T == Concrete {}
39+
40+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P4b@
41+
// CHECK-NEXT: Requirement signature: <Self where Self : P3b, Self.T == Concrete>
42+
43+
protocol P4b : P3b where T == Concrete {}
44+
45+
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P5@
46+
// CHECK-NEXT: Requirement signature: <Self where Self.T == Concrete>
47+
48+
protocol P5 {
49+
associatedtype T : P2 where T.A == T.B, T == Concrete
50+
}

0 commit comments

Comments
 (0)