@@ -35,8 +35,9 @@ namespace swift {
35
35
36
36
namespace rewriting {
37
37
38
- class RewriteContext ;
39
38
class MutableTerm ;
39
+ class RewriteContext ;
40
+ class Term ;
40
41
41
42
// / The smallest element in the rewrite system.
42
43
// /
@@ -46,35 +47,68 @@ class MutableTerm;
46
47
// / case type([Protocol], Identifier)
47
48
// / case genericParam(index: Int, depth: Int)
48
49
// / case layout(LayoutConstraint)
50
+ // / case superclass(CanType, substitutions: [Term])
51
+ // / case concrete(CanType, substitutions: [Term])
49
52
// / }
50
53
// /
54
+ // / For the concrete type atoms (`superclass` and `concrete`),
55
+ // / the type's structural components must either be concrete, or
56
+ // / generic parameters. All generic parameters must have a depth
57
+ // / of 0; the generic parameter index corresponds to an index in
58
+ // / the `substitutions` array.
59
+ // /
60
+ // / For example, the superclass requirement
61
+ // / "T : MyClass<U.X, (Int) -> V.A.B>" is denoted with an atom
62
+ // / structured as follows:
63
+ // /
64
+ // / - type: MyClass<τ_0_0, (Int) -> τ_0_1>
65
+ // / - substitutions:
66
+ // / - U.X
67
+ // / - V.A.B
68
+ // /
51
69
// / Out-of-line methods are documented in RewriteSystem.cpp.
52
70
class Atom final {
53
71
public:
54
72
enum class Kind : uint8_t {
73
+ // ////
74
+ // //// "Type-like" atom kinds:
75
+ // ////
76
+
55
77
// / An associated type [P:T] or [P&Q&...:T]. The parent term
56
78
// / must be known to conform to P (or P, Q, ...).
57
79
AssociatedType,
58
80
59
81
// / A generic parameter, uniquely identified by depth and
60
82
// / index. Can only appear at the beginning of a term, where
61
- // / it represents a generic parameter of the top-level generic
83
+ // / it denotes a generic parameter of the top-level generic
62
84
// / signature.
63
85
GenericParam,
64
86
65
87
// / An unbound identifier name.
66
88
Name,
67
89
68
- // / When appearing at the start of a term, represents a nested
90
+ // ////
91
+ // //// "Fact-like" atom kinds:
92
+ // ////
93
+
94
+ // / When appearing at the start of a term, denotes a nested
69
95
// / type of a protocol 'Self' type.
70
96
// /
71
- // / When appearing at the end of a term, represents that the
72
- // / term conforms to the protocol.
97
+ // / When appearing at the end of a term, denotes that the
98
+ // / term's type conforms to the protocol.
73
99
Protocol,
74
100
75
- // / When appearring at the end of a term, represents that the
76
- // / term conforms to the layout.
77
- Layout
101
+ // / When appearing at the end of a term, denotes that the
102
+ // / term's type satisfies the layout constraint.
103
+ Layout,
104
+
105
+ // / When appearing at the end of a term, denotes that the term
106
+ // / is a subclass of the superclass constraint.
107
+ Superclass,
108
+
109
+ // / When appearing at the end of a term, denotes that the term
110
+ // / is exactly equal to the concrete type.
111
+ ConcreteType,
78
112
};
79
113
80
114
private:
@@ -100,6 +134,12 @@ class Atom final {
100
134
101
135
LayoutConstraint getLayoutConstraint () const ;
102
136
137
+ CanType getSuperclass () const ;
138
+
139
+ CanType getConcreteType () const ;
140
+
141
+ ArrayRef<Term> getSubstitutions () const ;
142
+
103
143
// / Returns an opaque pointer that uniquely identifies this atom.
104
144
const void *getOpaquePointer () const {
105
145
return Ptr;
@@ -125,6 +165,14 @@ class Atom final {
125
165
static Atom forLayout (LayoutConstraint layout,
126
166
RewriteContext &ctx);
127
167
168
+ static Atom forSuperclass (CanType type,
169
+ ArrayRef<Term> substitutions,
170
+ RewriteContext &ctx);
171
+
172
+ static Atom forConcreteType (CanType type,
173
+ ArrayRef<Term> substitutions,
174
+ RewriteContext &ctx);
175
+
128
176
int compare (Atom other, const ProtocolGraph &protos) const ;
129
177
130
178
void dump (llvm::raw_ostream &out) const ;
@@ -170,151 +218,14 @@ class Term final {
170
218
171
219
Atom operator [](size_t index) const ;
172
220
173
- static Term get (const MutableTerm &term, RewriteContext &ctx);
174
-
175
- void dump (llvm::raw_ostream &out) const ;
176
- };
177
-
178
- // / Atoms are uniqued and immutable, stored as a single pointer;
179
- // / the Storage type is the allocated backing storage.
180
- struct Atom ::Storage final
181
- : public llvm::FoldingSetNode,
182
- public llvm::TrailingObjects<Storage, const ProtocolDecl *, Term> {
183
- friend class Atom ;
184
-
185
- unsigned Kind : 3 ;
186
- unsigned NumProtocols : 15 ;
187
- unsigned NumSubstitutions : 14 ;
188
-
189
- union {
190
- Identifier Name;
191
- LayoutConstraint Layout;
192
- const ProtocolDecl *Proto;
193
- GenericTypeParamType *GenericParam;
194
- };
195
-
196
- explicit Storage (Identifier name) {
197
- Kind = unsigned (Atom::Kind::Name);
198
- NumProtocols = 0 ;
199
- NumSubstitutions = 0 ;
200
- Name = name;
201
- }
202
-
203
- explicit Storage (LayoutConstraint layout) {
204
- Kind = unsigned (Atom::Kind::Layout);
205
- NumProtocols = 0 ;
206
- NumSubstitutions = 0 ;
207
- Layout = layout;
208
- }
209
-
210
- explicit Storage (const ProtocolDecl *proto) {
211
- Kind = unsigned (Atom::Kind::Protocol);
212
- NumProtocols = 0 ;
213
- NumSubstitutions = 0 ;
214
- Proto = proto;
215
- }
216
-
217
- explicit Storage (GenericTypeParamType *param) {
218
- Kind = unsigned (Atom::Kind::GenericParam);
219
- NumProtocols = 0 ;
220
- NumSubstitutions = 0 ;
221
- GenericParam = param;
222
- }
223
-
224
- Storage (ArrayRef<const ProtocolDecl *> protos, Identifier name) {
225
- assert (!protos.empty ());
226
-
227
- Kind = unsigned (Atom::Kind::AssociatedType);
228
- NumProtocols = protos.size ();
229
- assert (NumProtocols == protos.size () && " Overflow" );
230
- NumSubstitutions = 0 ;
231
- Name = name;
232
-
233
- for (unsigned i : indices (protos))
234
- getProtocols ()[i] = protos[i];
235
- }
236
-
237
- size_t numTrailingObjects (OverloadToken<const ProtocolDecl *>) const {
238
- return NumProtocols;
239
- }
240
-
241
- size_t numTrailingObjects (OverloadToken<Term>) const {
242
- return NumSubstitutions;
243
- }
244
-
245
- MutableArrayRef<const ProtocolDecl *> getProtocols () {
246
- return {getTrailingObjects<const ProtocolDecl *>(), NumProtocols};
247
- }
248
-
249
- ArrayRef<const ProtocolDecl *> getProtocols () const {
250
- return {getTrailingObjects<const ProtocolDecl *>(), NumProtocols};
251
- }
252
-
253
- void Profile (llvm::FoldingSetNodeID &id) {
254
- id.AddInteger (Kind);
255
-
256
- switch (Atom::Kind (Kind)) {
257
- case Atom::Kind::Name:
258
- id.AddPointer (Name.get ());
259
- return ;
260
-
261
- case Atom::Kind::Layout:
262
- id.AddPointer (Layout.getPointer ());
263
- return ;
264
-
265
- case Atom::Kind::Protocol:
266
- id.AddPointer (Proto);
267
- return ;
268
-
269
- case Atom::Kind::GenericParam:
270
- id.AddPointer (GenericParam);
271
- return ;
272
-
273
- case Atom::Kind::AssociatedType: {
274
- auto protos = getProtocols ();
275
- id.AddInteger (protos.size ());
276
-
277
- for (const auto *proto : protos)
278
- id.AddPointer (proto);
279
-
280
- id.AddPointer (Name.get ());
281
- return ;
282
- }
283
- }
284
-
285
- llvm_unreachable (" Bad atom kind" );
286
- }
287
- };
288
-
289
- // / Terms are uniqued and immutable, stored as a single pointer;
290
- // / the Storage type is the allocated backing storage.
291
- struct Term ::Storage final
292
- : public llvm::FoldingSetNode,
293
- public llvm::TrailingObjects<Storage, Atom> {
294
- friend class Atom ;
295
-
296
- unsigned Size;
297
-
298
- explicit Storage (unsigned size) : Size(size) {}
299
-
300
- size_t numTrailingObjects (OverloadToken<Atom>) const {
301
- return Size;
302
- }
303
-
304
- MutableArrayRef<Atom> getElements () {
305
- return {getTrailingObjects<Atom>(), Size};
306
- }
307
-
308
- ArrayRef<Atom> getElements () const {
309
- return {getTrailingObjects<Atom>(), Size};
221
+ // / Returns an opaque pointer that uniquely identifies this term.
222
+ const void *getOpaquePointer () const {
223
+ return Ptr;
310
224
}
311
225
312
- void Profile (llvm::FoldingSetNodeID &id) {
313
- id.AddInteger (Size);
226
+ static Term get (const MutableTerm &term, RewriteContext &ctx);
314
227
315
- for (auto atom : getElements ())
316
- id.AddPointer (atom.getOpaquePointer ());
317
- }
228
+ void dump (llvm::raw_ostream &out) const ;
318
229
};
319
230
320
231
// / A term is a sequence of one or more atoms.
0 commit comments