Skip to content

Commit 80223ed

Browse files
authored
Merge pull request #40835 from slavapestov/rqm-more-relations-everywhere
RequirementMachine: Generalize relations so they look more like rules
2 parents b7bebfe + da30258 commit 80223ed

16 files changed

+292
-661
lines changed

lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ add_swift_host_library(swiftAST STATIC
7979
RequirementMachine/KnuthBendix.cpp
8080
RequirementMachine/MinimalConformances.cpp
8181
RequirementMachine/PropertyMap.cpp
82+
RequirementMachine/PropertyRelations.cpp
8283
RequirementMachine/PropertyUnification.cpp
8384
RequirementMachine/RequirementLowering.cpp
8485
RequirementMachine/RequirementMachine.cpp

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
8686

8787
for (auto step : Path) {
8888
switch (step.Kind) {
89-
case RewriteStep::ApplyRewriteRule: {
89+
case RewriteStep::Rule: {
9090
if (!step.isInContext() && !evaluator.isInContext())
9191
rulesInEmptyContext.insert(step.getRuleID());
9292

@@ -98,11 +98,6 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
9898
case RewriteStep::Shift:
9999
case RewriteStep::Decompose:
100100
case RewriteStep::Relation:
101-
case RewriteStep::ConcreteConformance:
102-
case RewriteStep::SuperclassConformance:
103-
case RewriteStep::ConcreteTypeWitness:
104-
case RewriteStep::SameTypeWitness:
105-
case RewriteStep::AbstractTypeWitness:
106101
break;
107102
}
108103

@@ -207,7 +202,7 @@ RewritePath RewritePath::splitCycleAtRule(unsigned ruleID) const {
207202

208203
for (auto step : Steps) {
209204
switch (step.Kind) {
210-
case RewriteStep::ApplyRewriteRule: {
205+
case RewriteStep::Rule: {
211206
if (step.getRuleID() != ruleID)
212207
break;
213208

@@ -222,11 +217,6 @@ RewritePath RewritePath::splitCycleAtRule(unsigned ruleID) const {
222217
case RewriteStep::Shift:
223218
case RewriteStep::Decompose:
224219
case RewriteStep::Relation:
225-
case RewriteStep::ConcreteConformance:
226-
case RewriteStep::SuperclassConformance:
227-
case RewriteStep::ConcreteTypeWitness:
228-
case RewriteStep::SameTypeWitness:
229-
case RewriteStep::AbstractTypeWitness:
230220
break;
231221
}
232222

@@ -263,7 +253,7 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
263253
bool foundAny = false;
264254

265255
for (const auto &step : Steps) {
266-
if (step.Kind == RewriteStep::ApplyRewriteRule &&
256+
if (step.Kind == RewriteStep::Rule &&
267257
step.getRuleID() == ruleID) {
268258
foundAny = true;
269259
break;
@@ -283,7 +273,7 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
283273

284274
for (const auto &step : Steps) {
285275
switch (step.Kind) {
286-
case RewriteStep::ApplyRewriteRule: {
276+
case RewriteStep::Rule: {
287277
if (step.getRuleID() != ruleID) {
288278
newSteps.push_back(step);
289279
break;
@@ -324,11 +314,6 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
324314
case RewriteStep::Shift:
325315
case RewriteStep::Decompose:
326316
case RewriteStep::Relation:
327-
case RewriteStep::ConcreteConformance:
328-
case RewriteStep::SuperclassConformance:
329-
case RewriteStep::ConcreteTypeWitness:
330-
case RewriteStep::SameTypeWitness:
331-
case RewriteStep::AbstractTypeWitness:
332317
newSteps.push_back(step);
333318
break;
334319
}

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void RewriteLoop::findProtocolConformanceRules(
112112
for (const auto &step : Path) {
113113
if (!evaluator.isInContext()) {
114114
switch (step.Kind) {
115-
case RewriteStep::ApplyRewriteRule: {
115+
case RewriteStep::Rule: {
116116
const auto &rule = system.getRule(step.getRuleID());
117117

118118
if (rule.isIdentityConformanceRule())
@@ -138,11 +138,6 @@ void RewriteLoop::findProtocolConformanceRules(
138138
case RewriteStep::Shift:
139139
case RewriteStep::Decompose:
140140
case RewriteStep::Relation:
141-
case RewriteStep::ConcreteConformance:
142-
case RewriteStep::SuperclassConformance:
143-
case RewriteStep::ConcreteTypeWitness:
144-
case RewriteStep::SameTypeWitness:
145-
case RewriteStep::AbstractTypeWitness:
146141
break;
147142
}
148143
}
@@ -268,7 +263,7 @@ MinimalConformances::decomposeTermIntoConformanceRuleLeftHandSides(
268263
assert(!rule.isIdentityConformanceRule());
269264
#endif
270265

271-
assert(step.Kind == RewriteStep::ApplyRewriteRule);
266+
assert(step.Kind == RewriteStep::Rule);
272267
assert(step.EndOffset == 0);
273268
assert(!step.Inverse);
274269

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//===--- PropertyRelations.cpp - Relations between property rules ---------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/AST/Type.h"
14+
#include "llvm/Support/raw_ostream.h"
15+
#include <algorithm>
16+
#include "RewriteSystem.h"
17+
18+
using namespace swift;
19+
using namespace rewriting;
20+
21+
RewriteSystem::Relation
22+
RewriteSystem::getRelation(unsigned index) const {
23+
return Relations[index];
24+
}
25+
26+
/// Record a relation that transforms the left hand side when it appears
27+
/// at the end of a term to the right hand side. Returns the relation ID,
28+
/// which can be passed to RewriteStep::forRelation().
29+
unsigned RewriteSystem::recordRelation(Term lhs, Term rhs) {
30+
auto key = std::make_pair(lhs, rhs);
31+
auto found = RelationMap.find(key);
32+
if (found != RelationMap.end())
33+
return found->second;
34+
35+
unsigned index = Relations.size();
36+
Relations.push_back(key);
37+
auto inserted = RelationMap.insert(std::make_pair(key, index));
38+
assert(inserted.second);
39+
(void) inserted;
40+
41+
return index;
42+
}
43+
44+
/// Given a left-hand side symbol [p1] and a right-hand side symbol
45+
/// [p2], record a relation ([p1].[p2] => [p1]), which denotes that
46+
/// the property p1 implies the property p2.
47+
///
48+
/// An example is a superclass requirement that implies a layout
49+
/// requirement.
50+
unsigned RewriteSystem::recordRelation(Symbol lhsProperty,
51+
Symbol rhsProperty) {
52+
assert(lhsProperty.isProperty());
53+
assert(rhsProperty.isProperty());
54+
55+
MutableTerm lhsTerm;
56+
lhsTerm.add(lhsProperty);
57+
lhsTerm.add(rhsProperty);
58+
59+
MutableTerm rhsTerm;
60+
rhsTerm.add(lhsProperty);
61+
62+
// Record a relation ([p1].[p2] => [p1]).
63+
return recordRelation(
64+
Term::get(lhsTerm, Context),
65+
Term::get(rhsTerm, Context));
66+
}
67+
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
71+
/// symbol to form a single a concrete conformance symbol.
72+
unsigned RewriteSystem::recordConcreteConformanceRelation(
73+
Symbol concreteSymbol, Symbol protocolSymbol,
74+
Symbol concreteConformanceSymbol) {
75+
assert(protocolSymbol.getKind() == Symbol::Kind::Protocol);
76+
assert(protocolSymbol.getProtocol() ==
77+
concreteConformanceSymbol.getProtocol());
78+
assert(concreteSymbol.getKind() == Symbol::Kind::Superclass ||
79+
concreteSymbol.getKind() == Symbol::Kind::ConcreteType);
80+
81+
MutableTerm lhsTerm;
82+
lhsTerm.add(concreteSymbol);
83+
lhsTerm.add(protocolSymbol);
84+
85+
MutableTerm rhsTerm;
86+
rhsTerm.add(concreteConformanceSymbol);
87+
88+
return recordRelation(
89+
Term::get(lhsTerm, Context),
90+
Term::get(rhsTerm, Context));
91+
}
92+
93+
/// Record a relation ([concrete: C : P].[P:X].[concrete: C.X] =>
94+
/// [concrete: C : P].[P:X]) which "concretizes" a nested type C.X of a
95+
/// type parameter conforming to P known to equal the concrete type C.
96+
unsigned RewriteSystem::recordConcreteTypeWitnessRelation(
97+
Symbol concreteConformanceSymbol,
98+
Symbol associatedTypeSymbol,
99+
Symbol typeWitnessSymbol) {
100+
assert(concreteConformanceSymbol.getKind() ==
101+
Symbol::Kind::ConcreteConformance);
102+
assert(associatedTypeSymbol.getKind() ==
103+
Symbol::Kind::AssociatedType);
104+
assert(associatedTypeSymbol.getProtocols().size() == 1);
105+
assert(concreteConformanceSymbol.getProtocol() ==
106+
associatedTypeSymbol.getProtocols()[0]);
107+
assert(typeWitnessSymbol.getKind() == Symbol::Kind::ConcreteType);
108+
109+
MutableTerm rhsTerm;
110+
rhsTerm.add(concreteConformanceSymbol);
111+
rhsTerm.add(associatedTypeSymbol);
112+
113+
MutableTerm lhsTerm(rhsTerm);
114+
lhsTerm.add(typeWitnessSymbol);
115+
116+
return recordRelation(
117+
Term::get(lhsTerm, Context),
118+
Term::get(rhsTerm, Context));
119+
}
120+
121+
/// Record a relation ([concrete: C : P].[P:X].[concrete: C] =>
122+
/// [concrete: C : P].[P:X]) which "ties off" a nested type C.X that is
123+
/// equivalent to C.
124+
unsigned RewriteSystem::recordSameTypeWitnessRelation(
125+
Symbol concreteConformanceSymbol,
126+
Symbol associatedTypeSymbol) {
127+
assert(concreteConformanceSymbol.getKind() ==
128+
Symbol::Kind::ConcreteConformance);
129+
assert(associatedTypeSymbol.getKind() ==
130+
Symbol::Kind::AssociatedType);
131+
132+
MutableTerm rhsTerm;
133+
rhsTerm.add(concreteConformanceSymbol);
134+
135+
auto concreteSymbol = Symbol::forConcreteType(
136+
concreteConformanceSymbol.getConcreteType(),
137+
concreteConformanceSymbol.getSubstitutions(),
138+
Context);
139+
MutableTerm lhsTerm(rhsTerm);
140+
lhsTerm.add(associatedTypeSymbol);
141+
lhsTerm.add(concreteSymbol);
142+
143+
return recordRelation(
144+
Term::get(lhsTerm, Context),
145+
Term::get(rhsTerm, Context));
146+
}

0 commit comments

Comments
 (0)