Skip to content

Commit 9801a05

Browse files
authored
Merge pull request #40514 from slavapestov/rqm-validation-test-fixes
RequirementMachine: More fixes for validation tests with -requirement-machine-protocol-signatures=verify
2 parents 856ce2d + 49274cc commit 9801a05

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,11 @@ namespace {
150150
/// Utility class to encapsulate some shared state.
151151
class GeneratingConformances {
152152
const RewriteSystem &System;
153+
153154
RewriteContext &Context;
154155

156+
DebugOptions Debug;
157+
155158
// All conformance rules, sorted by (isExplicit(), getLHS()), with non-explicit
156159
// rules with longer left hand sides coming first.
157160
//
@@ -209,6 +212,7 @@ class GeneratingConformances {
209212
llvm::DenseSet<unsigned> &redundantConformances)
210213
: System(system),
211214
Context(system.getRewriteContext()),
215+
Debug(system.getDebugOptions()),
212216
RedundantConformances(redundantConformances) {}
213217

214218
void collectConformanceRules();
@@ -481,7 +485,7 @@ void GeneratingConformances::computeCandidateConformancePaths() {
481485
if (result.empty())
482486
continue;
483487

484-
if (System.getDebugOptions().contains(DebugFlags::GeneratingConformances)) {
488+
if (Debug.contains(DebugFlags::GeneratingConformances)) {
485489
llvm::dbgs() << "Candidate homotopy generator: ";
486490
loop.dump(llvm::dbgs(), System);
487491
llvm::dbgs() << "\n";
@@ -497,7 +501,7 @@ void GeneratingConformances::computeCandidateConformancePaths() {
497501
if (inEmptyContext.empty())
498502
continue;
499503

500-
if (System.getDebugOptions().contains(DebugFlags::GeneratingConformances)) {
504+
if (Debug.contains(DebugFlags::GeneratingConformances)) {
501505
llvm::dbgs() << "* Protocol " << proto->getName() << ":\n";
502506
llvm::dbgs() << "** Conformance rules not in context:\n";
503507
for (unsigned ruleID : inEmptyContext) {
@@ -755,7 +759,7 @@ void GeneratingConformances::verifyGeneratingConformanceEquations() const {
755759
llvm::errs() << "Mismatched conformance:\n";
756760
llvm::errs() << "Base rule: " << rule << "\n";
757761
llvm::errs() << "Final rule: " << otherRule << "\n\n";
758-
System.dump(llvm::errs());
762+
dumpGeneratingConformanceEquations(llvm::errs());
759763
abort();
760764
}
761765

@@ -772,7 +776,7 @@ void GeneratingConformances::verifyGeneratingConformanceEquations() const {
772776
pair.first, pair.second);
773777
llvm::errs() << "\n";
774778
llvm::errs() << "Term: " << rule << "\n";
775-
System.dump(llvm::errs());
779+
dumpGeneratingConformanceEquations(llvm::errs());
776780
abort();
777781
}
778782

@@ -789,7 +793,7 @@ void GeneratingConformances::verifyGeneratingConformanceEquations() const {
789793
llvm::errs() << "Invalid conformance path:\n";
790794
llvm::errs() << "Expected: " << baseTerm << "\n";
791795
llvm::errs() << "Got: " << otherTerm << "\n\n";
792-
System.dump(llvm::errs());
796+
dumpGeneratingConformanceEquations(llvm::errs());
793797
abort();
794798
}
795799
}
@@ -811,7 +815,12 @@ void GeneratingConformances::computeGeneratingConformances(
811815
bool derivedViaConcrete = false;
812816
for (const auto &path : paths) {
813817
if (path.empty())
814-
break;
818+
continue;
819+
820+
// If the rule is itself a concrete conformance, it is not
821+
// derived-via-concrete via itself.
822+
if (path.size() == 1 && path.front() == ruleID)
823+
continue;
815824

816825
if (System.getRule(path.back()).getLHS().back().getKind() ==
817826
Symbol::Kind::ConcreteConformance) {
@@ -824,6 +833,12 @@ void GeneratingConformances::computeGeneratingConformances(
824833
// considered in the second pass.
825834
if (!derivedViaConcrete)
826835
continue;
836+
837+
if (Debug.contains(DebugFlags::GeneratingConformances)) {
838+
llvm::dbgs() << "Derived-via-concrete: ";
839+
dumpGeneratingConformanceEquation(llvm::dbgs(), ruleID, paths);
840+
llvm::dbgs() << "\n";
841+
}
827842
} else {
828843
// Ignore rules already determined to be redundant by the first pass.
829844
if (RedundantConformances.count(ruleID) > 0)
@@ -843,6 +858,14 @@ void GeneratingConformances::computeGeneratingConformances(
843858

844859
if (isValidConformancePath(visited, path,
845860
/*allowConcrete=*/true)) {
861+
if (Debug.contains(DebugFlags::GeneratingConformances)) {
862+
llvm::dbgs() << "Redundant rule in ";
863+
llvm::dbgs() << (firstPass ? "first" : "second");
864+
llvm::dbgs() << " pass: ";
865+
llvm::dbgs() << System.getRule(ruleID).getLHS();
866+
llvm::dbgs() << "\n";
867+
}
868+
846869
RedundantConformances.insert(ruleID);
847870
break;
848871
}
@@ -869,7 +892,7 @@ void GeneratingConformances::verifyGeneratingConformances() const {
869892
/*allowConcrete=*/true)) {
870893
llvm::errs() << "Redundant conformance is not recoverable:\n";
871894
llvm::errs() << rule << "\n\n";
872-
System.dump(llvm::errs());
895+
dumpGeneratingConformanceEquations(llvm::errs());
873896
abort();
874897
}
875898

@@ -879,14 +902,14 @@ void GeneratingConformances::verifyGeneratingConformances() const {
879902
if (rule.isRedundant()) {
880903
llvm::errs() << "Generating conformance is redundant: ";
881904
llvm::errs() << rule << "\n\n";
882-
System.dump(llvm::errs());
905+
dumpGeneratingConformanceEquations(llvm::errs());
883906
abort();
884907
}
885908

886909
if (rule.getLHS().containsUnresolvedSymbols()) {
887910
llvm::errs() << "Generating conformance contains unresolved symbols: ";
888911
llvm::errs() << rule << "\n\n";
889-
System.dump(llvm::errs());
912+
dumpGeneratingConformanceEquations(llvm::errs());
890913
abort();
891914
}
892915
}

lib/AST/RequirementMachine/RewriteContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ void RewriteContext::getProtocolComponentRec(
626626

627627
/// Lazily construct a requirement machine for the given protocol's strongly
628628
/// connected component (SCC) in the protocol dependency graph.
629+
///
630+
/// This can only be called once, to prevent multiple requirement machines
631+
/// for being built with the same component.
629632
ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent(
630633
const ProtocolDecl *proto) {
631634
auto found = Protos.find(proto);
@@ -650,6 +653,8 @@ ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent(
650653
abort();
651654
}
652655

656+
component.InProgress = true;
657+
653658
return component.Protos;
654659
}
655660

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
3+
protocol Sequence {}
4+
5+
protocol Collection : Sequence {}
6+
7+
struct MyCollection : Collection {}
8+
9+
// CHECK-LABEL: inherited_concrete_conformance_in_protocol.(file).P@
10+
// CHECK-LABEL: Requirement signature: <Self where Self.T == MyCollection>
11+
12+
protocol P {
13+
associatedtype T : Collection where T == MyCollection
14+
}

0 commit comments

Comments
 (0)