Skip to content

Commit 7380062

Browse files
authored
Merge pull request #42165 from slavapestov/rqm-propagate-requirement-id-debug
RequirementMachine: More debug output from 'propagateRedundantRequirementIDs()' and some other small tweaks
2 parents d727a79 + 41c04c5 commit 7380062

File tree

5 files changed

+64
-27
lines changed

5 files changed

+64
-27
lines changed

lib/AST/RequirementMachine/ConcreteContraction.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,17 @@ bool ConcreteContraction::performConcreteContraction(
599599
// requirement where the left hand side is not a type parameter.
600600
SmallVector<Requirement, 4> reqs;
601601
if (req.inferred) {
602+
// Discard errors from desugaring a substituted requirement that
603+
// was inferred. For example, if we have something like
604+
//
605+
// <T, U where T == Int, U == Set<T>>
606+
//
607+
// The inferred requirement 'T : Hashable' from 'Set<>' will
608+
// be substituted with 'T == Int' to get 'Int : Hashable'.
609+
//
610+
// Desugaring will diagnose a redundant conformance requirement,
611+
// but we want to ignore that, since the user did not explicitly
612+
// write 'Int : Hashable' (or 'T : Hashable') anywhere.
602613
SmallVector<RequirementError, 4> discardErrors;
603614
desugarRequirement(substReq, SourceLoc(), reqs, discardErrors);
604615
} else {

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -126,39 +126,51 @@ void RewriteSystem::propagateRedundantRequirementIDs() {
126126
llvm::dbgs() << "\nPropagating requirement IDs: {";
127127
}
128128

129-
for (auto ruleAndReplacement : RedundantRules) {
130-
auto ruleID = ruleAndReplacement.first;
131-
auto rewritePath = ruleAndReplacement.second;
132-
auto &rule = Rules[ruleID];
129+
for (const auto &ruleAndReplacement : RedundantRules) {
130+
unsigned ruleID = ruleAndReplacement.first;
131+
const auto &rewritePath = ruleAndReplacement.second;
132+
const auto &rule = Rules[ruleID];
133133

134134
auto requirementID = rule.getRequirementID();
135-
if (!requirementID.hasValue())
135+
if (!requirementID.hasValue()) {
136+
if (Debug.contains(DebugFlags::PropagateRequirementIDs)) {
137+
llvm::dbgs() << "\n- rule does not have a requirement ID: "
138+
<< rule;
139+
}
136140
continue;
141+
}
137142

138143
MutableTerm lhs(rule.getLHS());
139-
for (auto ruleID : rewritePath.getRulesInEmptyContext(lhs, *this)) {
144+
for (auto ruleID : rewritePath.findRulesAppearingOnceInEmptyContext(lhs, *this)) {
140145
auto &replacement = Rules[ruleID];
141-
if (!replacement.isPermanent()) {
142-
// If the replacement rule already has a requirementID, overwrite
143-
// it if the existing ID corresponds to an inferred requirement.
144-
// This effectively makes the inferred requirement the redundant
145-
// one, which makes it easier to suppress redundancy warnings for
146-
// inferred requirements later on.
147-
auto existingID = replacement.getRequirementID();
148-
if (existingID.hasValue() && !WrittenRequirements[*existingID].inferred)
149-
continue;
146+
if (replacement.isPermanent()) {
147+
if (Debug.contains(DebugFlags::PropagateRequirementIDs)) {
148+
llvm::dbgs() << "\n- skipping permanent rule: " << rule;
149+
}
150+
continue;
151+
}
150152

153+
// If the replacement rule already has a requirementID, overwrite
154+
// it if the existing ID corresponds to an inferred requirement.
155+
// This effectively makes the inferred requirement the redundant
156+
// one, which makes it easier to suppress redundancy warnings for
157+
// inferred requirements later on.
158+
auto existingID = replacement.getRequirementID();
159+
if (existingID.hasValue() && !WrittenRequirements[*existingID].inferred) {
151160
if (Debug.contains(DebugFlags::PropagateRequirementIDs)) {
152-
llvm::dbgs() << "\n- propagating ID = "
153-
<< requirementID
154-
<< "\n from ";
155-
rule.dump(llvm::dbgs());
156-
llvm::dbgs() << "\n to ";
157-
replacement.dump(llvm::dbgs());
161+
llvm::dbgs() << "\n- rule already has a requirement ID: "
162+
<< rule;
158163
}
164+
continue;
165+
}
159166

160-
replacement.setRequirementID(requirementID);
167+
if (Debug.contains(DebugFlags::PropagateRequirementIDs)) {
168+
llvm::dbgs() << "\n- propagating ID = " << requirementID
169+
<< "\n from " << rule;
170+
llvm::dbgs() << "\n to " << replacement;
161171
}
172+
173+
replacement.setRequirementID(requirementID);
162174
}
163175
}
164176

lib/AST/RequirementMachine/RewriteLoop.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,8 @@ bool RewritePath::replaceRuleWithPath(unsigned ruleID,
345345
}
346346

347347
SmallVector<unsigned, 1>
348-
RewritePath::getRulesInEmptyContext(const MutableTerm &term,
349-
const RewriteSystem &system) {
348+
RewritePath::findRulesAppearingOnceInEmptyContext(const MutableTerm &term,
349+
const RewriteSystem &system) const {
350350
// Rules appearing in empty context (possibly more than once).
351351
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
352352
// The number of times each rule appears (with or without context).
@@ -485,7 +485,8 @@ void RewriteLoop::recompute(const RewriteSystem &system) {
485485
evaluator.apply(step, system);
486486
}
487487

488-
RulesInEmptyContext = Path.getRulesInEmptyContext(Basepoint, system);
488+
RulesInEmptyContext =
489+
Path.findRulesAppearingOnceInEmptyContext(Basepoint, system);
489490
}
490491

491492
/// A rewrite rule is redundant if it appears exactly once in a loop

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,9 @@ class RewritePath {
411411

412412
bool replaceRuleWithPath(unsigned ruleID, const RewritePath &path);
413413

414-
SmallVector<unsigned, 1> getRulesInEmptyContext(const MutableTerm &term,
415-
const RewriteSystem &system);
414+
SmallVector<unsigned, 1>
415+
findRulesAppearingOnceInEmptyContext(const MutableTerm &term,
416+
const RewriteSystem &system) const;
416417

417418
void invert();
418419

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,5 +910,17 @@ void RewriteSystem::dump(llvm::raw_ostream &out) const {
910910
out << "\n";
911911
}
912912
}
913+
if (!WrittenRequirements.empty()) {
914+
out << "Written requirements: {\n";
915+
916+
for (unsigned reqID : indices(WrittenRequirements)) {
917+
out << " - ID: " << reqID << " - ";
918+
const auto &requirement = WrittenRequirements[reqID];
919+
requirement.req.dump(out);
920+
out << " at ";
921+
requirement.loc.print(out, Context.getASTContext().SourceMgr);
922+
out << "\n";
923+
}
924+
}
913925
out << "}\n";
914926
}

0 commit comments

Comments
 (0)