@@ -31,6 +31,17 @@ namespace swift {
3131
3232namespace rewriting {
3333
34+ // / The most primitive term in the rewrite system.
35+ // /
36+ // / enum Atom {
37+ // / case name(Identifier)
38+ // / case protocol(Protocol)
39+ // / case type([Protocol], Identifier)
40+ // / case genericParam(index: Int, depth: Int)
41+ // / case layout(LayoutConstraint)
42+ // / }
43+ // /
44+ // / Out-of-line methods are documented in RewriteSystem.cpp.
3445class Atom final {
3546 using Storage = llvm::PointerUnion<Identifier,
3647 GenericTypeParamType *,
@@ -47,42 +58,70 @@ class Atom final {
4758 }
4859
4960public:
61+ // / Creates a new name atom.
5062 static Atom forName (Identifier name) {
5163 return Atom ({}, name);
5264 }
5365
66+ // / Creates a new protocol atom.
5467 static Atom forProtocol (const ProtocolDecl *proto) {
5568 return Atom ({proto}, Storage ());
5669 }
5770
71+ // / Creates a new associated type atom for a single protocol.
5872 static Atom forAssociatedType (const ProtocolDecl *proto,
5973 Identifier name) {
6074 assert (proto != nullptr );
6175 return Atom ({proto}, name);
6276 }
6377
78+ // / Creates a merged associated type atom to represent a nested
79+ // / type that conforms to multiple protocols, all of which have
80+ // / an associated type with the same name.
6481 static Atom forAssociatedType (
6582 llvm::TinyPtrVector<const ProtocolDecl *>protos,
6683 Identifier name) {
6784 assert (!protos.empty ());
6885 return Atom (protos, name);
6986 }
7087
88+ // / Creates a generic parameter atom, representing a generic
89+ // / parameter in the top-level generic signature from which the
90+ // / rewrite system is built.
7191 static Atom forGenericParam (GenericTypeParamType *param) {
7292 assert (param->isCanonical ());
7393 return Atom ({}, param);
7494 }
7595
96+ // / Creates a layout atom, representing a layout constraint.
7697 static Atom forLayout (LayoutConstraint layout) {
7798 assert (layout->isKnownLayout ());
7899 return Atom ({}, layout);
79100 }
80101
81102 enum class Kind : uint8_t {
103+ // / An associated type [P:T] or [P&Q&...:T]. The parent term
104+ // / must be known to conform to P (or P, Q, ...).
82105 AssociatedType,
106+
107+ // / A generic parameter, uniquely identified by depth and
108+ // / index. Can only appear at the beginning of a term, where
109+ // / it represents a generic parameter of the top-level generic
110+ // / signature.
83111 GenericParam,
112+
113+ // / An unbound identifier name.
84114 Name,
115+
116+ // / When appearing at the start of a term, represents a nested
117+ // / type of a protocol 'Self' type.
118+ // /
119+ // / When appearing at the end of a term, represents that the
120+ // / term conforms to the protocol.
85121 Protocol,
122+
123+ // / When appearring at the end of a term, represents that the
124+ // / term conforms to the layout.
86125 Layout
87126 };
88127
@@ -111,30 +150,37 @@ class Atom final {
111150 llvm_unreachable (" Bad term rewriting atom" );
112151 }
113152
153+ // / Get the identifier associated with an unbound name atom or an
154+ // / associated type atom.
114155 Identifier getName () const {
115156 assert (getKind () == Kind::Name ||
116157 getKind () == Kind::AssociatedType);
117158 return Value.get <Identifier>();
118159 }
119160
161+ // / Get the single protocol declaration associate with a protocol atom.
120162 const ProtocolDecl *getProtocol () const {
121163 assert (getKind () == Kind::Protocol);
122164 assert (Protos.size () == 1 );
123165 return Protos.front ();
124166 }
125167
168+ // / Get the list of protocols associated with a protocol or associated
169+ // / type atom.
126170 llvm::TinyPtrVector<const ProtocolDecl *> getProtocols () const {
127171 assert (getKind () == Kind::Protocol ||
128172 getKind () == Kind::AssociatedType);
129173 assert (!Protos.empty ());
130174 return Protos;
131175 }
132176
177+ // / Get the generic parameter associated with a generic parameter atom.
133178 GenericTypeParamType *getGenericParam () const {
134179 assert (getKind () == Kind::GenericParam);
135180 return Value.get <GenericTypeParamType *>();
136181 }
137182
183+ // / Get the layout constraint associated with a layout constraint atom.
138184 LayoutConstraint getLayoutConstraint () const {
139185 assert (getKind () == Kind::Layout);
140186 return Value.get <LayoutConstraint>();
@@ -156,6 +202,14 @@ class Atom final {
156202 }
157203};
158204
205+ // / A term is a sequence of one or more atoms.
206+ // /
207+ // / The first atom in the term must be a protocol, generic parameter, or
208+ // / associated type atom.
209+ // /
210+ // / A layout constraint atom must only appear at the end of a term.
211+ // /
212+ // / Out-of-line methods are documented in RewriteSystem.cpp.
159213class Term final {
160214 llvm::SmallVector<Atom, 3 > Atoms;
161215
@@ -202,6 +256,7 @@ class Term final {
202256
203257 decltype (Atoms)::iterator findSubTerm (const Term &other);
204258
259+ // / Returns true if this term contains, or is equal to, \p other.
205260 bool containsSubTerm (const Term &other) const {
206261 return findSubTerm (other) != end ();
207262 }
@@ -213,6 +268,11 @@ class Term final {
213268 void dump (llvm::raw_ostream &out) const ;
214269};
215270
271+ // / A rewrite rule that replaces occurrences of LHS with RHS.
272+ // /
273+ // / LHS must be greater than RHS in the linear order over terms.
274+ // /
275+ // / Out-of-line methods are documented in RewriteSystem.cpp.
216276class Rule final {
217277 Term LHS;
218278 Term RHS;
@@ -238,19 +298,27 @@ class Rule final {
238298 return LHS.containsSubTerm (other.LHS );
239299 }
240300
301+ // / Returns if the rule was deleted.
241302 bool isDeleted () const {
242303 return deleted;
243304 }
244305
306+ // / Deletes the rule, which removes it from consideration in term
307+ // / simplification and completion. Deleted rules are simply marked as
308+ // / such instead of being physically removed from the rules vector
309+ // / in the rewrite system, to ensure that indices remain valid across
310+ // / deletion.
245311 void markDeleted () {
246312 assert (!deleted);
247313 deleted = true ;
248314 }
249315
316+ // / Returns the length of the left hand side.
250317 unsigned getDepth () const {
251318 return LHS.size ();
252319 }
253320
321+ // / Partial order on rules orders rules by their left hand side.
254322 int compare (const Rule &other,
255323 const ProtocolGraph &protos) const {
256324 return LHS.compare (other.LHS , protos);
@@ -259,12 +327,35 @@ class Rule final {
259327 void dump (llvm::raw_ostream &out) const ;
260328};
261329
330+ // / A term rewrite system for working with types in a generic signature.
331+ // /
332+ // / Out-of-line methods are documented in RewriteSystem.cpp.
262333class RewriteSystem final {
334+ // / The rules added so far, including rules from our client, as well
335+ // / as rules introduced by the completion procedure.
263336 std::vector<Rule> Rules;
337+
338+ // / The graph of all protocols transitively referenced via our set of
339+ // / rewrite rules, used for the linear order on atoms.
264340 ProtocolGraph Protos;
341+
342+ // / A list of pending terms for the associated type merging completion
343+ // / heuristic.
344+ // /
345+ // / The pair (lhs, rhs) satisfies the following conditions:
346+ // / - lhs > rhs
347+ // / - all atoms but the last are pair-wise equal in lhs and rhs
348+ // / - the last atom in both lhs and rhs is an associated type atom
349+ // / - the last atom in both lhs and rhs has the same name
350+ // /
351+ // / See RewriteSystem::processMergedAssociatedTypes() for details.
265352 std::vector<std::pair<Term, Term>> MergedAssociatedTypes;
353+
354+ // / A list of pending pairs for checking overlap in the completion
355+ // / procedure.
266356 std::deque<std::pair<unsigned , unsigned >> Worklist;
267357
358+ // / Set these to true to enable debugging output.
268359 unsigned DebugSimplify : 1 ;
269360 unsigned DebugAdd : 1 ;
270361 unsigned DebugMerge : 1 ;
@@ -291,8 +382,14 @@ class RewriteSystem final {
291382 bool simplify (Term &term) const ;
292383
293384 enum class CompletionResult {
385+ // / Confluent completion was computed successfully.
294386 Success,
387+
388+ // / Maximum number of iterations reached.
295389 MaxIterations,
390+
391+ // / Completion produced a rewrite rule whose left hand side has a length
392+ // / exceeding the limit.
296393 MaxDepth
297394 };
298395
0 commit comments