Skip to content

Commit 6b558d2

Browse files
authored
Merge pull request swiftlang#40119 from slavapestov/requirement-machine-explicit-conformances
RequirementMachine: Prefer to eliminate non-explicit conformances, and other fixes
2 parents 9acf26b + 2c4cfdc commit 6b558d2

17 files changed

+4366
-118
lines changed

docs/RequirementMachine/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
RequirementMachine.pdf:
2+
pdflatex RequirementMachine
3+
bibtex RequirementMachine
4+
pdflatex RequirementMachine
5+
pdflatex RequirementMachine
6+
7+
clean:
8+
rm *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.pdf *.toc
9+
10+
.PHONY: clean
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
@misc{se0142,
2+
author = "David Hart and Jacob Bandes-Storch and Doug Gregor",
3+
title = "{SE-0142}: Permit where clauses to constrain associated types",
4+
url = "https://github.com/apple/swift-evolution/blob/main/proposals/0142-associated-types-constraints.md",
5+
year = {2017}
6+
}
7+
@misc{se0157,
8+
author = "Doug Gregor and Erica Sadun and Austin Zheng",
9+
title = "{SE-0157}: Support recursive constraints on associated types",
10+
url = "https://github.com/apple/swift-evolution/blob/main/proposals/0157-recursive-protocol-constraints.md",
11+
year = {2017}
12+
}
13+
@misc(gensig,
14+
author = "Doug Gregor",
15+
title = "Generic Signatures",
16+
url = "https://github.com/apple/swift/blob/main/docs/ABI/GenericSignature.md",
17+
year = {2018}
18+
)
19+
@article{undecidablegroup,
20+
author = {Donald J. Collins},
21+
title = {{A simple presentation of a group with unsolvable word problem}},
22+
volume = {30},
23+
journal = {Illinois Journal of Mathematics},
24+
number = {2},
25+
publisher = {Duke University Press},
26+
pages = {230 -- 234},
27+
year = {1986},
28+
doi = {10.1215/ijm/1256044631},
29+
URL = {https://doi.org/10.1215/ijm/1256044631}
30+
}
31+
@book{andallthat, place={Cambridge}, title={Term Rewriting and All That}, DOI={10.1017/CBO9781139172752}, publisher={Cambridge University Press}, author={Baader, Franz and Nipkow, Tobias}, year={1998}}
32+
@Inbook{Knuth1983,
33+
author="Knuth, D. E.
34+
and Bendix, P. B.",
35+
editor="Siekmann, J{\"o}rg H.
36+
and Wrightson, Graham",
37+
title="Simple Word Problems in Universal Algebras",
38+
bookTitle="Automation of Reasoning: 2: Classical Papers on Computational Logic 1967--1970",
39+
year="1983",
40+
publisher="Springer Berlin Heidelberg",
41+
address="Berlin, Heidelberg",
42+
pages="342--376",
43+
isbn="978-3-642-81955-1",
44+
doi="10.1007/978-3-642-81955-1_23",
45+
url="https://doi.org/10.1007/978-3-642-81955-1_23"
46+
}
47+
@article{SQUIER1994271,
48+
title = {A finiteness condition for rewriting systems},
49+
journal = {Theoretical Computer Science},
50+
volume = {131},
51+
number = {2},
52+
pages = {271-294},
53+
year = {1994},
54+
issn = {0304-3975},
55+
doi = {https://doi.org/10.1016/0304-3975(94)90175-9},
56+
url = {https://www.sciencedirect.com/science/article/pii/0304397594901759},
57+
author = {Craig C. Squier and Friedrich Otto and Yuji Kobayashi}
58+
}
59+
@inproceedings{guiraud:hal-00818253,
60+
TITLE = {{A Homotopical Completion Procedure with Applications to Coherence of Monoids}},
61+
AUTHOR = {Guiraud, Yves and Malbos, Philippe and Mimram, Samuel},
62+
URL = {https://hal.inria.fr/hal-00818253},
63+
BOOKTITLE = {{RTA - 24th International Conference on Rewriting Techniques and Applications - 2013}},
64+
ADDRESS = {Eindhoven, Netherlands},
65+
EDITOR = {Van Raamsdonk, Femke},
66+
PUBLISHER = {{Schloss Dagstuhl--Leibniz-Zentrum fuer Informatik}},
67+
SERIES = {Leibniz International Proceedings in Informatics (LIPIcs)},
68+
VOLUME = {21},
69+
PAGES = {223-238},
70+
YEAR = {2013},
71+
MONTH = Jun,
72+
DOI = {10.4230/LIPIcs.RTA.2013.223},
73+
HAL_ID = {hal-00818253},
74+
HAL_VERSION = {v1},
75+
}

docs/RequirementMachine/RequirementMachine.tex

Lines changed: 3832 additions & 0 deletions
Large diffs are not rendered by default.

lib/AST/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ add_swift_host_library(swiftAST STATIC
7474
ProtocolConformance.cpp
7575
RawComment.cpp
7676
RequirementEnvironment.cpp
77-
RequirementMachine/HomotopyReduction.cpp
7877
RequirementMachine/GeneratingConformances.cpp
7978
RequirementMachine/GenericSignatureQueries.cpp
79+
RequirementMachine/HomotopyReduction.cpp
80+
RequirementMachine/KnuthBendix.cpp
8081
RequirementMachine/PropertyMap.cpp
8182
RequirementMachine/PropertyUnification.cpp
8283
RequirementMachine/RequirementMachine.cpp
8384
RequirementMachine/RequirementMachineRequests.cpp
8485
RequirementMachine/RewriteContext.cpp
8586
RequirementMachine/RewriteLoop.cpp
8687
RequirementMachine/RewriteSystem.cpp
87-
RequirementMachine/RewriteSystemCompletion.cpp
8888
RequirementMachine/Symbol.cpp
8989
RequirementMachine/Term.cpp
9090
SILLayout.cpp

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,13 @@ static const ProtocolDecl *getParentConformanceForTerm(Term lhs) {
607607
/// conformance rules.
608608
void RewriteSystem::computeGeneratingConformances(
609609
llvm::DenseSet<unsigned> &redundantConformances) {
610-
// All conformance rules, sorted by left hand side.
611-
SmallVector<std::pair<unsigned, Term>, 4> conformanceRules;
610+
// All conformance rules, sorted by (isExplicit(), getLHS()), with non-explicit
611+
// rules with longer left hand sides coming first.
612+
//
613+
// The idea here is that we want less canonical rules to be eliminated first,
614+
// but we prefer to eliminate non-explicit rules, in an attempt to keep protocol
615+
// conformance rules in the same protocol as they were originally defined in.
616+
SmallVector<unsigned, 4> conformanceRules;
612617

613618
// Maps a conformance rule to a conformance path deriving the subject type's
614619
// base type. For example, consider the following conformance rule:
@@ -640,8 +645,7 @@ void RewriteSystem::computeGeneratingConformances(
640645
if (!rule.isProtocolConformanceRule())
641646
continue;
642647

643-
auto lhs = rule.getLHS();
644-
conformanceRules.emplace_back(ruleID, lhs);
648+
conformanceRules.push_back(ruleID);
645649

646650
// Initially, every non-redundant conformance rule can be expressed
647651
// as itself.
@@ -655,6 +659,8 @@ void RewriteSystem::computeGeneratingConformances(
655659
continue;
656660
}
657661

662+
auto lhs = rule.getLHS();
663+
658664
// Record a parent path if the subject type itself requires a non-trivial
659665
// conformance path to derive.
660666
if (auto *parentProto = getParentConformanceForTerm(lhs)) {
@@ -696,14 +702,18 @@ void RewriteSystem::computeGeneratingConformances(
696702
// Sort the list of conformance rules in reverse order; we're going to try
697703
// to minimize away less canonical rules first.
698704
std::sort(conformanceRules.begin(), conformanceRules.end(),
699-
[&](const std::pair<unsigned, Term> &lhs,
700-
const std::pair<unsigned, Term> &rhs) -> bool {
701-
return lhs.second.compare(rhs.second, Context) > 0;
705+
[&](unsigned lhs, unsigned rhs) -> bool {
706+
const auto &lhsRule = getRule(lhs);
707+
const auto &rhsRule = getRule(rhs);
708+
709+
if (lhsRule.isExplicit() != rhsRule.isExplicit())
710+
return !lhsRule.isExplicit();
711+
712+
return lhsRule.getLHS().compare(rhsRule.getLHS(), Context) > 0;
702713
});
703714

704715
// Find a minimal set of generating conformances.
705-
for (const auto &pair : conformanceRules) {
706-
unsigned ruleID = pair.first;
716+
for (unsigned ruleID : conformanceRules) {
707717
const auto &paths = conformancePaths[ruleID];
708718

709719
bool isProtocolRefinement = protocolRefinements.count(ruleID) > 0;

0 commit comments

Comments
 (0)