Skip to content

Commit 2bca132

Browse files
committed
RequirementMachine: Introduce RewriteStep::AbstractTypeWitness
1 parent 4c83fe8 commit 2bca132

File tree

4 files changed

+76
-8
lines changed

4 files changed

+76
-8
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ RewriteLoop::findRulesAppearingOnceInEmptyContext(
101101
case RewriteStep::SuperclassConformance:
102102
case RewriteStep::ConcreteTypeWitness:
103103
case RewriteStep::SameTypeWitness:
104+
case RewriteStep::AbstractTypeWitness:
104105
break;
105106
}
106107

@@ -223,6 +224,7 @@ RewritePath RewritePath::splitCycleAtRule(unsigned ruleID) const {
223224
case RewriteStep::SuperclassConformance:
224225
case RewriteStep::ConcreteTypeWitness:
225226
case RewriteStep::SameTypeWitness:
227+
case RewriteStep::AbstractTypeWitness:
226228
break;
227229
}
228230

@@ -323,6 +325,7 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
323325
case RewriteStep::SuperclassConformance:
324326
case RewriteStep::ConcreteTypeWitness:
325327
case RewriteStep::SameTypeWitness:
328+
case RewriteStep::AbstractTypeWitness:
326329
newSteps.push_back(step);
327330
break;
328331
}

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ void RewriteLoop::findProtocolConformanceRules(
141141
case RewriteStep::SuperclassConformance:
142142
case RewriteStep::ConcreteTypeWitness:
143143
case RewriteStep::SameTypeWitness:
144+
case RewriteStep::AbstractTypeWitness:
144145
break;
145146
}
146147
}

lib/AST/RequirementMachine/RewriteLoop.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ void RewriteStep::dump(llvm::raw_ostream &out,
9292
: "SameTypeWitness");
9393
break;
9494
}
95+
case AbstractTypeWitness: {
96+
evaluator.applyAbstractTypeWitness(*this, system);
97+
98+
out << (Inverse ? "AbstractTypeWitness⁻¹"
99+
: "AbstractTypeWitness");
100+
break;
101+
}
95102

96103
}
97104
}
@@ -561,6 +568,42 @@ void RewritePathEvaluator::applySameTypeWitness(const RewriteStep &step,
561568
}
562569
}
563570

571+
void
572+
RewritePathEvaluator::applyAbstractTypeWitness(const RewriteStep &step,
573+
const RewriteSystem &system) {
574+
checkA();
575+
auto &term = A.back();
576+
577+
const auto &witness = system.getTypeWitness(step.RuleID);
578+
auto fail = [&]() {
579+
llvm::errs() << "Bad abstract type witness term:\n";
580+
llvm::errs() << term << "\n\n";
581+
witness.dump(llvm::errs());
582+
abort();
583+
};
584+
585+
auto typeWitness = witness.getAbstractType();
586+
587+
Term origTerm = (step.Inverse ? witness.LHS : typeWitness);
588+
Term substTerm = (step.Inverse ? typeWitness : witness.LHS);
589+
590+
if (term.size() != step.StartOffset + origTerm.size() + step.EndOffset) {
591+
fail();
592+
}
593+
594+
if (!std::equal(origTerm.begin(),
595+
origTerm.end(),
596+
term.begin() + step.StartOffset)) {
597+
fail();
598+
}
599+
600+
MutableTerm newTerm(term.begin(), term.begin() + step.StartOffset);
601+
newTerm.append(substTerm);
602+
newTerm.append(term.end() - step.EndOffset, term.end());
603+
604+
term = newTerm;
605+
}
606+
564607
void RewritePathEvaluator::apply(const RewriteStep &step,
565608
const RewriteSystem &system) {
566609
switch (step.Kind) {
@@ -592,5 +635,9 @@ void RewritePathEvaluator::apply(const RewriteStep &step,
592635
case RewriteStep::SameTypeWitness:
593636
applySameTypeWitness(step, system);
594637
break;
638+
639+
case RewriteStep::AbstractTypeWitness:
640+
applyAbstractTypeWitness(step, system);
641+
break;
595642
}
596643
}

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,30 +132,39 @@ struct RewriteStep {
132132
/// The RuleID field is a TypeWitness ID as above.
133133
/// the step.
134134
SameTypeWitness,
135+
136+
/// If not inverted: replaces the abstract type witness term with the
137+
/// subject type term.
138+
///
139+
/// If inverted: replaces the subject type term with the abstract type
140+
/// term.
141+
///
142+
/// The RuleID field is a TypeWitness ID as above.
143+
AbstractTypeWitness,
135144
};
136145

137146
/// The rewrite step kind.
138-
StepKind Kind : 3;
147+
StepKind Kind : 4;
148+
149+
/// If false, the step replaces an occurrence of the rule's left hand side
150+
/// with the right hand side. If true, vice versa.
151+
unsigned Inverse : 1;
139152

140153
/// The size of the left whisker, which is the position within the term where
141154
/// the rule is being applied. In A.(X => Y).B, this is |A|=1.
142-
unsigned StartOffset : 14;
155+
unsigned StartOffset : 16;
143156

144157
/// The size of the right whisker, which is the length of the remaining suffix
145158
/// after the rule is applied. In A.(X => Y).B, this is |B|=1.
146-
unsigned EndOffset : 14;
159+
unsigned EndOffset : 16;
147160

148161
/// If Kind is ApplyRewriteRule, the index of the rule in the rewrite system.
149162
///
150163
/// If Kind is AdjustConcreteType, the length of the prefix to add or remove
151164
/// at the beginning of each concrete substitution.
152165
///
153166
/// If Kind is Concrete, the number of substitutions to push or pop.
154-
unsigned RuleID : 15;
155-
156-
/// If false, the step replaces an occurrence of the rule's left hand side
157-
/// with the right hand side. If true, vice versa.
158-
unsigned Inverse : 1;
167+
unsigned RuleID : 16;
159168

160169
RewriteStep(StepKind kind, unsigned startOffset, unsigned endOffset,
161170
unsigned ruleID, bool inverse) {
@@ -211,6 +220,11 @@ struct RewriteStep {
211220
/*ruleID=*/witnessID, inverse);
212221
}
213222

223+
static RewriteStep forAbstractTypeWitness(unsigned witnessID, bool inverse) {
224+
return RewriteStep(AbstractTypeWitness, /*startOffset=*/0, /*endOffset=*/0,
225+
/*ruleID=*/witnessID, inverse);
226+
}
227+
214228
bool isInContext() const {
215229
return StartOffset > 0 || EndOffset > 0;
216230
}
@@ -400,6 +414,9 @@ struct RewritePathEvaluator {
400414
void applySameTypeWitness(const RewriteStep &step,
401415
const RewriteSystem &system);
402416

417+
void applyAbstractTypeWitness(const RewriteStep &step,
418+
const RewriteSystem &system);
419+
403420
void dump(llvm::raw_ostream &out) const;
404421
};
405422

0 commit comments

Comments
 (0)