Skip to content

Commit b6a641b

Browse files
committed
RequirementMachine: New way of introducing concrete conformance rules
Define the relation as [concrete: C].[P] =>> [concrete: C].[concrete: C : P] instead of [concrete: C].[P] =>> [concrete: C : P] This changes the rewrite loop recorded for a rule T.[concrete: C : P] to have (T.[concrete: C] => T) appearing twice in context instead of just once. We don't ever want a concrete conformance rule to be able to imply a concrete type rule. This became possible with loop normalization because the single occurrence of (T.[concrete: C] => T).[P] could cancel with a subsequent step (T => T.[concrete: C]).[P] in another rewrite loop after substitution.
1 parent 95f122f commit b6a641b

7 files changed

+92
-4
lines changed

lib/AST/RequirementMachine/ConcreteTypeWitness.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,14 +483,29 @@ void PropertyMap::recordConcreteConformanceRule(
483483

484484
auto protocolSymbol = *conformanceRule.isPropertyRule();
485485

486-
// Now, transform T''.[concrete: C].[P] into T''.[concrete: C : P].
486+
// Now, transform T''.[concrete: C].[P] into T''.[concrete: C].[concrete: C : P].
487487
unsigned relationID = System.recordConcreteConformanceRelation(
488488
concreteSymbol, protocolSymbol, concreteConformanceSymbol);
489489

490490
path.add(RewriteStep::forRelation(
491491
/*startOffset=*/rhs.size(), relationID,
492492
/*inverse=*/false));
493493

494+
// If T' is a suffix of T, prepend the prefix to the concrete type's
495+
// substitutions.
496+
if (prefixLength > 0 &&
497+
!concreteConformanceSymbol.getSubstitutions().empty()) {
498+
path.add(RewriteStep::forPrefixSubstitutions(prefixLength, /*endOffset=*/1,
499+
/*inverse=*/true));
500+
}
501+
502+
// Finally, apply the concrete type rule to obtain T''.[concrete: C : P].
503+
path.add(RewriteStep::forRewriteRule(
504+
/*startOffset=*/rhs.size() - concreteRule.getRHS().size(),
505+
/*endOffset=*/1,
506+
/*ruleID=*/concreteRuleID,
507+
/*inverse=*/false));
508+
494509
MutableTerm lhs(rhs);
495510
lhs.add(concreteConformanceSymbol);
496511

lib/AST/RequirementMachine/PropertyRelations.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ unsigned RewriteSystem::recordRelation(Symbol lhsProperty,
6565
Term::get(rhsTerm, Context));
6666
}
6767

68-
/// Record a relation ([concrete: C].[P] => [concrete: C : P])
69-
/// or ([superclass: C].[P] => [concrete: C : P]) which combines a
70-
/// concrete type symbol (or a superclass symbol) with a protocol
68+
/// Record a relation ([concrete: C].[P] => [concrete: C].[concrete: C : P])
69+
/// or ([superclass: C].[P] => [superclass: C].[concrete: C : P]) which combines
70+
/// a concrete type symbol (or a superclass symbol) with a protocol
7171
/// symbol to form a single a concrete conformance symbol.
7272
unsigned RewriteSystem::recordConcreteConformanceRelation(
7373
Symbol concreteSymbol, Symbol protocolSymbol,
@@ -83,6 +83,7 @@ unsigned RewriteSystem::recordConcreteConformanceRelation(
8383
lhsTerm.add(protocolSymbol);
8484

8585
MutableTerm rhsTerm;
86+
rhsTerm.add(concreteSymbol);
8687
rhsTerm.add(concreteConformanceSymbol);
8788

8889
return recordRelation(

test/Generics/concrete_conformance_minimization.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s
22
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction 2>&1 | %FileCheck %s
3+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s
34

45
struct MyOptionSet : OptionSet {
56
let rawValue: UInt

test/Generics/concrete_conformance_rule_simplified.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s
22
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction 2>&1 | %FileCheck %s
3+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -disable-requirement-machine-concrete-contraction -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s
34

45
protocol P1 {}
56

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s
2+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s
3+
4+
protocol P {
5+
associatedtype T
6+
}
7+
8+
struct C {}
9+
10+
// CHECK-LABEL: .f1@
11+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
12+
func f1<T: P, U: P>(_: T, _: U) where T.T == C, T.T == U.T { }
13+
14+
// CHECK-LABEL: .f2@
15+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
16+
func f2<T: P, U: P>(_: T, _: U) where U.T == C, T.T == U.T { }
17+
18+
// CHECK-LABEL: .f3@
19+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
20+
func f3<T: P, U: P>(_: T, _: U) where T.T == C, U.T == C, T.T == U.T { }
21+
22+
// CHECK-LABEL: .f4@
23+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
24+
func f4<T: P, U: P>(_: T, _: U) where T.T == C, T.T == U.T, U.T == C { }
25+
26+
// CHECK-LABEL: .f5@
27+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
28+
func f5<T: P, U: P>(_: T, _: U) where T.T == U.T, T.T == C, U.T == C { }
29+
30+
// CHECK-LABEL: .f6@
31+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
32+
func f6<T: P, U: P>(_: T, _: U) where U.T == C, T.T == C, T.T == U.T { }
33+
34+
// CHECK-LABEL: .f7@
35+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
36+
func f7<T: P, U: P>(_: T, _: U) where T.T == C, U.T == C, T.T == U.T { }
37+
38+
// CHECK-LABEL: .f8@
39+
// CHECK-NEXT: Generic signature: <T, U where T : P, U : P, T.[P]T == C, U.[P]T == C>
40+
func f8<T: P, U: P>(_: T, _: U) where T.T == U.T, U.T == C, T.T == C { }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s
3+
4+
protocol P1 {
5+
associatedtype A
6+
}
7+
8+
protocol P2 : P1 where A == S0 {
9+
associatedtype B : P2 = S2
10+
where B.A == A, B.B == B
11+
}
12+
13+
struct S0 {}
14+
15+
struct S1 : P2 {}
16+
17+
struct S2 : P2 {}
18+
19+
// CHECK-LABEL: .Q1@
20+
// CHECK-NEXT: Requirement signature: <Self where Self.[Q1]T == S1>
21+
protocol Q1 {
22+
associatedtype T where T : P2, T == S1
23+
}
24+
25+
// CHECK-LABEL: .Q2@
26+
// CHECK-NEXT: Requirement signature: <Self where Self.[Q2]T == S2>
27+
protocol Q2 {
28+
associatedtype T where T : P2, T == S2
29+
}

test/Generics/redundant_parent_path_in_protocol.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on -enable-requirement-machine-loop-normalization 2>&1 | %FileCheck %s
23

34
// CHECK-LABEL: redundant_parent_path_in_protocol.(file).P1@
45
// CHECK-NEXT: Requirement signature: <Self>

0 commit comments

Comments
 (0)