Skip to content

Commit 34cbfd2

Browse files
committed
RequirementMachine: Don't assert if a rewrite system has unresolved rules
This is a source-level error, not an invariant violation. Instead, plumb a new hadError() flag, which in the future will assert if no diagnostic was produced.
1 parent 81ac321 commit 34cbfd2

File tree

6 files changed

+52
-31
lines changed

6 files changed

+52
-31
lines changed

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@ void RewriteSystem::computeGeneratingConformances(
646646
if (rule.isRedundant())
647647
continue;
648648

649+
if (rule.containsUnresolvedSymbols())
650+
continue;
651+
649652
if (!rule.isProtocolConformanceRule())
650653
continue;
651654

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,23 @@ void RewriteSystem::minimizeRewriteSystem() {
790790
verifyMinimizedRules();
791791
}
792792

793+
/// In a conformance-valid rewrite system, any rule with unresolved symbols on
794+
/// the left or right hand side should have been simplified by another rule.
795+
bool RewriteSystem::hasNonRedundantUnresolvedRules() const {
796+
assert(Complete);
797+
assert(Minimized);
798+
799+
for (const auto &rule : Rules) {
800+
if (!rule.isRedundant() &&
801+
!rule.isPermanent() &&
802+
rule.containsUnresolvedSymbols()) {
803+
return true;
804+
}
805+
}
806+
807+
return false;
808+
}
809+
793810
/// Collect all non-permanent, non-redundant rules whose domain is equal to
794811
/// one of the protocols in \p proto. In other words, the first symbol of the
795812
/// left hand side term is either a protocol symbol or associated type symbol
@@ -805,11 +822,11 @@ RewriteSystem::getMinimizedProtocolRules(
805822
for (unsigned ruleID : indices(Rules)) {
806823
const auto &rule = getRule(ruleID);
807824

808-
if (rule.isPermanent())
809-
continue;
810-
811-
if (rule.isRedundant())
825+
if (rule.isPermanent() ||
826+
rule.isRedundant() ||
827+
rule.containsUnresolvedSymbols()) {
812828
continue;
829+
}
813830

814831
auto domain = rule.getLHS()[0].getProtocols();
815832
assert(domain.size() == 1);
@@ -834,11 +851,11 @@ RewriteSystem::getMinimizedGenericSignatureRules() const {
834851
for (unsigned ruleID : indices(Rules)) {
835852
const auto &rule = getRule(ruleID);
836853

837-
if (rule.isPermanent())
838-
continue;
839-
840-
if (rule.isRedundant())
854+
if (rule.isPermanent() ||
855+
rule.isRedundant() ||
856+
rule.containsUnresolvedSymbols()) {
841857
continue;
858+
}
842859

843860
if (rule.getLHS()[0].getKind() != Symbol::Kind::GenericParam)
844861
continue;
@@ -917,29 +934,17 @@ void RewriteSystem::verifyMinimizedRules() const {
917934
continue;
918935
}
919936

920-
if (rule.isRedundant())
921-
continue;
922-
923937
// Simplified rules should be redundant, unless they're protocol conformance
924938
// rules, which unfortunately might no be redundant, because we try to keep
925939
// them in the original protocol definition for compatibility with the
926940
// GenericSignatureBuilder's minimization algorithm.
927-
if (rule.isSimplified() && !rule.isProtocolConformanceRule()) {
941+
if (rule.isSimplified() &&
942+
!rule.isRedundant() &&
943+
!rule.isProtocolConformanceRule()) {
928944
llvm::errs() << "Simplified rule is not redundant: " << rule << "\n\n";
929945
dump(llvm::errs());
930946
abort();
931947
}
932-
933-
// Rules with unresolved name symbols (other than permanent rules for
934-
// associated type introduction) should be redundant.
935-
//
936-
// FIXME: What about invalid code?
937-
if (rule.getLHS().containsUnresolvedSymbols() ||
938-
rule.getRHS().containsUnresolvedSymbols()) {
939-
llvm::errs() << "Unresolved rule is not redundant: " << rule << "\n\n";
940-
dump(llvm::errs());
941-
abort();
942-
}
943948
}
944949
#endif
945950
}

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ bool RequirementMachine::isComplete() const {
256256
return Complete;
257257
}
258258

259+
bool RequirementMachine::hadError() const {
260+
// FIXME: Implement other checks here
261+
// FIXME: Assert if hadError() is true but we didn't emit any diagnostics?
262+
return System.hasNonRedundantUnresolvedRules();
263+
}
264+
259265
void RequirementMachine::dump(llvm::raw_ostream &out) const {
260266
out << "Requirement machine for ";
261267
if (Sig)

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class RequirementMachine final {
137137

138138
std::vector<Requirement> computeMinimalGenericSignatureRequirements();
139139

140+
bool hadError() const;
141+
140142
void verify(const MutableTerm &term) const;
141143
void dump(llvm::raw_ostream &out) const;
142144

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,9 @@ AbstractGenericSignatureRequestRQM::evaluate(
359359
auto minimalRequirements =
360360
machine->computeMinimalGenericSignatureRequirements();
361361

362-
// FIXME: Implement this
363-
bool hadError = false;
364-
365362
auto result = GenericSignature::get(genericParams, minimalRequirements);
363+
bool hadError = machine->hadError();
364+
366365
return GenericSignatureWithError(result, hadError);
367366
}
368367

@@ -463,10 +462,8 @@ InferredGenericSignatureRequestRQM::evaluate(
463462
auto minimalRequirements =
464463
machine->computeMinimalGenericSignatureRequirements();
465464

466-
// FIXME: Implement this
467-
bool hadError = false;
468-
469465
auto result = GenericSignature::get(genericParams, minimalRequirements);
466+
bool hadError = machine->hadError();
470467

471468
// FIXME: Handle allowConcreteGenericParams
472469

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ class Rule final {
103103
return Redundant;
104104
}
105105

106+
bool containsUnresolvedSymbols() const {
107+
return (LHS.containsUnresolvedSymbols() ||
108+
RHS.containsUnresolvedSymbols());
109+
}
110+
106111
void markSimplified() {
107112
assert(!Simplified);
108113
Simplified = true;
@@ -314,8 +319,6 @@ class RewriteSystem final {
314319

315320
void checkMergedAssociatedType(Term lhs, Term rhs);
316321

317-
public:
318-
319322
//////////////////////////////////////////////////////////////////////////////
320323
///
321324
/// Homotopy reduction
@@ -337,13 +340,17 @@ class RewriteSystem final {
337340
void performHomotopyReduction(
338341
const llvm::DenseSet<unsigned> *redundantConformances);
339342

343+
public:
340344
void minimizeRewriteSystem();
341345

346+
bool hasNonRedundantUnresolvedRules() const;
347+
342348
llvm::DenseMap<const ProtocolDecl *, std::vector<unsigned>>
343349
getMinimizedProtocolRules(ArrayRef<const ProtocolDecl *> protos) const;
344350

345351
std::vector<unsigned> getMinimizedGenericSignatureRules() const;
346352

353+
private:
347354
void verifyRewriteLoops() const;
348355

349356
void verifyRedundantConformances(
@@ -398,6 +405,7 @@ class RewriteSystem final {
398405
void computeGeneratingConformances(
399406
llvm::DenseSet<unsigned> &redundantConformances);
400407

408+
public:
401409
void dump(llvm::raw_ostream &out) const;
402410
};
403411

0 commit comments

Comments
 (0)