Skip to content

Commit b1a3d2c

Browse files
committed
RequirementMachine: Preserve rewrite path for simplifying substitutions
1 parent 317743a commit b1a3d2c

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,6 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
736736
Context, result);
737737
auto typeWitnessSymbol =
738738
Symbol::forConcreteType(typeWitnessSchema, result, Context);
739-
System.simplifySubstitutions(typeWitnessSymbol);
740739

741740
auto concreteConformanceSymbol = *(subjectType.end() - 2);
742741
auto assocTypeSymbol = *(subjectType.end() - 1);
@@ -746,6 +745,11 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
746745
typeWitnessSymbol);
747746
unsigned witnessID = System.recordConcreteTypeWitness(witness);
748747

748+
// Simplify the substitution terms in the type witness symbol.
749+
RewritePath substPath;
750+
System.simplifySubstitutions(typeWitnessSymbol, &substPath);
751+
substPath.invert();
752+
749753
// If it is equal to the parent type, introduce a same-type requirement
750754
// between the two parameters.
751755
if (requirementKind == RequirementKind::SameType &&
@@ -758,13 +762,21 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
758762
llvm::dbgs() << "^^ Type witness is the same as the concrete type\n";
759763
}
760764

761-
// Add a rule T.[concrete: C : P].[P:X] => T.[concrete: C : P].
765+
// Add a rule T.[concrete: C : P] => T.[concrete: C : P].[P:X].
762766
MutableTerm result(key);
763767
result.add(concreteConformanceSymbol);
764768

769+
// ([concrete: C : P] => [concrete: C : P].[P:X].[concrete: C])
765770
path.add(RewriteStep::forSameTypeWitness(
766771
witnessID, /*inverse=*/true));
767772

773+
// [concrete: C : P].[P:X].([concrete: C] => [concrete: C.X])
774+
path.append(substPath);
775+
776+
// T.([concrete: C : P].[P:X].[concrete: C.X] => [concrete: C : P].[P:X])
777+
path.add(RewriteStep::forConcreteTypeWitness(
778+
witnessID, /*inverse=*/false));
779+
768780
return result;
769781
}
770782

@@ -795,10 +807,16 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
795807
//
796808
// Add a rule:
797809
//
798-
// T.[concrete: C : P].[P:X].[concrete: C.X] => T.[concrete: C : P].[P:X].
810+
// T.[concrete: C : P].[P:X].[concrete: C.X'] => T.[concrete: C : P].[P:X].
811+
//
812+
// Where C.X' is the canonical form of C.X.
799813
MutableTerm constraintType = subjectType;
800814
constraintType.add(typeWitnessSymbol);
801815

816+
// T.[concrete: C : P].[P:X].([concrete: C.X'] => [concrete: C.X])
817+
path.append(substPath);
818+
819+
// T.([concrete: C : P].[P:X].[concrete: C.X] => [concrete: C : P].[P:X])
802820
path.add(RewriteStep::forConcreteTypeWitness(
803821
witnessID, /*inverse=*/false));
804822

lib/AST/RequirementMachine/RewriteLoop.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,8 @@ void RewritePathEvaluator::applyConcreteTypeWitness(const RewriteStep &step,
443443
llvm::errs() << "Conformance: " << witness.ConcreteConformance << "\n";
444444
llvm::errs() << "Assoc type: " << witness.AssocType << "\n";
445445
llvm::errs() << "Concrete type: " << witness.ConcreteType << "\n";
446+
llvm::errs() << "End offset: " << step.EndOffset << "\n";
447+
llvm::errs() << "Inverse: " << step.Inverse << "\n";
446448
abort();
447449
};
448450

@@ -496,7 +498,7 @@ void RewritePathEvaluator::applySameTypeWitness(const RewriteStep &step,
496498

497499
const auto &witness = system.getConcreteTypeWitness(step.RuleID);
498500
auto fail = [&]() {
499-
llvm::errs() << "Bad concrete type witness term:\n";
501+
llvm::errs() << "Bad same-type witness term:\n";
500502
llvm::errs() << term << "\n\n";
501503
llvm::errs() << "Conformance: " << witness.ConcreteConformance << "\n";
502504
llvm::errs() << "Assoc type: " << witness.AssocType << "\n";
@@ -505,26 +507,30 @@ void RewritePathEvaluator::applySameTypeWitness(const RewriteStep &step,
505507
};
506508

507509
#ifndef NDEBUG
508-
if ((witness.ConcreteType.getConcreteType() !=
509-
witness.ConcreteConformance.getConcreteType()) ||
510-
(witness.ConcreteType.getSubstitutions() !=
511-
witness.ConcreteConformance.getSubstitutions())) {
510+
if (witness.ConcreteType.getConcreteType() !=
511+
witness.ConcreteConformance.getConcreteType()) {
512512
fail();
513513
}
514514
#endif
515515

516+
auto witnessConcreteType = Symbol::forConcreteType(
517+
witness.ConcreteConformance.getConcreteType(),
518+
witness.ConcreteConformance.getSubstitutions(),
519+
system.getRewriteContext());
520+
516521
if (!step.Inverse) {
517522
// Make sure the term takes the following form, where |V| == EndOffset:
518523
//
519-
// U.[concrete: C : P].[P:X].V
520-
if (term.size() <= step.EndOffset + 2 ||
521-
*(term.end() - step.EndOffset - 2) != witness.ConcreteConformance ||
522-
*(term.end() - step.EndOffset - 1) != witness.AssocType) {
524+
// U.[concrete: C : P].[P:X].[concrete: C].V
525+
if (term.size() <= step.EndOffset + 3 ||
526+
*(term.end() - step.EndOffset - 3) != witness.ConcreteConformance ||
527+
*(term.end() - step.EndOffset - 2) != witness.AssocType ||
528+
*(term.end() - step.EndOffset - 1) != witnessConcreteType) {
523529
fail();
524530
}
525531

526532
// Get the subterm U.[concrete: C : P].
527-
MutableTerm newTerm(term.begin(), term.end() - step.EndOffset - 1);
533+
MutableTerm newTerm(term.begin(), term.end() - step.EndOffset - 2);
528534

529535
// Add the subterm V, to get U.[concrete: C : P].V.
530536
newTerm.append(term.end() - step.EndOffset, term.end());
@@ -545,9 +551,12 @@ void RewritePathEvaluator::applySameTypeWitness(const RewriteStep &step,
545551
// Add the symbol [P:X].
546552
newTerm.add(witness.AssocType);
547553

554+
// Add the symbol [concrete: C].
555+
newTerm.add(witnessConcreteType);
556+
548557
// Add the subterm V, to get
549558
//
550-
// U.[concrete: C : P].[P:X].V
559+
// U.[concrete: C : P].[P:X].[concrete: C].V
551560
newTerm.append(term.end() - step.EndOffset, term.end());
552561

553562
term = newTerm;

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ class RewritePath {
249249
}
250250

251251
// Horizontal composition of paths.
252-
void append(RewritePath other) {
252+
void append(const RewritePath &other) {
253253
Steps.append(other.begin(), other.end());
254254
}
255255

0 commit comments

Comments
 (0)