@@ -82,6 +82,8 @@ class GenericSignatureBuilder {
82
82
83
83
class FloatingRequirementSource ;
84
84
85
+ class DelayedRequirement ;
86
+
85
87
// / Describes a specific constraint on a potential archetype.
86
88
template <typename T>
87
89
struct Constraint {
@@ -178,6 +180,35 @@ class GenericSignatureBuilder {
178
180
179
181
friend class RequirementSource ;
180
182
183
+ // / The result of introducing a new constraint.
184
+ enum class ConstraintResult {
185
+ // / The constraint was resolved and the relative potential archetypes
186
+ // / have been updated.
187
+ Resolved,
188
+
189
+ // / The constraint was written directly on a concrete type.
190
+ Concrete,
191
+
192
+ // / The constraint conflicted with existing constraints in some way;
193
+ // / the generic signature is ill-formed.
194
+ Conflicting,
195
+
196
+ // / The constraint could not be resolved immediately.
197
+ Unresolved,
198
+ };
199
+
200
+ // / Enum used to indicate how we should handle a constraint that cannot be
201
+ // / processed immediately for some reason.
202
+ enum class UnresolvedHandlingKind : char {
203
+ // / Generate a new, unresolved constraint and consider the constraint
204
+ // / "resolved" at this point.
205
+ GenerateConstraints = 0 ,
206
+
207
+ // / Do not generate a new constraint; rather, return
208
+ // / \c ConstraintResult::Unresolved and let the caller handle it.
209
+ ReturnUnresolved = 1 ,
210
+ };
211
+
181
212
private:
182
213
class InferRequirementsWalker ;
183
214
friend class InferRequirementsWalker ;
@@ -193,13 +224,15 @@ class GenericSignatureBuilder {
193
224
194
225
// / When a particular requirement cannot be resolved due to, e.g., a
195
226
// / currently-unresolvable or nested type, this routine should be
196
- // / called to record the unresolved requirement to be reconsidered later .
227
+ // / called to cope with the unresolved requirement.
197
228
// /
198
- // / \returns false, which is used elsewhere to indicate "no failure".
199
- bool recordUnresolvedRequirement (RequirementKind kind,
229
+ // / \returns \c ConstraintResult::Resolved or ConstraintResult::Delayed,
230
+ // / as appropriate based on \c unresolvedHandling.
231
+ ConstraintResult handleUnresolvedRequirement (RequirementKind kind,
200
232
UnresolvedType lhs,
201
233
RequirementRHS rhs,
202
- FloatingRequirementSource source);
234
+ FloatingRequirementSource source,
235
+ UnresolvedHandlingKind unresolvedHandling);
203
236
204
237
// / Retrieve the constraint source conformance for the superclass constraint
205
238
// / of the given potential archetype (if present) to the given protocol.
@@ -214,14 +247,15 @@ class GenericSignatureBuilder {
214
247
215
248
// / \brief Add a new conformance requirement specifying that the given
216
249
// / potential archetype conforms to the given protocol.
217
- bool addConformanceRequirement (PotentialArchetype *T,
218
- ProtocolDecl *Proto,
219
- const RequirementSource *Source);
250
+ ConstraintResult addConformanceRequirement (PotentialArchetype *T,
251
+ ProtocolDecl *Proto,
252
+ const RequirementSource *Source);
220
253
221
- bool addConformanceRequirement (PotentialArchetype *T,
222
- ProtocolDecl *Proto,
223
- const RequirementSource *Source,
224
- llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
254
+ ConstraintResult addConformanceRequirement (
255
+ PotentialArchetype *T,
256
+ ProtocolDecl *Proto,
257
+ const RequirementSource *Source,
258
+ llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
225
259
226
260
public:
227
261
// / \brief Add a new same-type requirement between two fully resolved types
@@ -231,7 +265,7 @@ class GenericSignatureBuilder {
231
265
// / incompatible (e.g. \c Foo<Bar<T>> and \c Foo<Baz>), \c diagnoseMismatch is
232
266
// / called with the two types that don't match (\c Bar<T> and \c Baz for the
233
267
// / previous example).
234
- bool
268
+ ConstraintResult
235
269
addSameTypeRequirementDirect (
236
270
ResolvedType paOrT1, ResolvedType paOrT2,
237
271
FloatingRequirementSource Source,
@@ -241,57 +275,67 @@ class GenericSignatureBuilder {
241
275
// / (output of GenericSignatureBuilder::resolve).
242
276
// /
243
277
// / The two types must not be incompatible concrete types.
244
- bool addSameTypeRequirementDirect (ResolvedType paOrT1, ResolvedType paOrT2,
245
- FloatingRequirementSource Source);
278
+ ConstraintResult addSameTypeRequirementDirect (
279
+ ResolvedType paOrT1,
280
+ ResolvedType paOrT2,
281
+ FloatingRequirementSource Source);
246
282
247
283
// / \brief Add a new same-type requirement between two unresolved types.
248
284
// /
249
285
// / The types are resolved with \c GenericSignatureBuilder::resolve, and must
250
286
// / not be incompatible concrete types.
251
- bool addSameTypeRequirement (UnresolvedType paOrT1, UnresolvedType paOrT2,
252
- FloatingRequirementSource Source);
287
+ ConstraintResult addSameTypeRequirement (
288
+ UnresolvedType paOrT1,
289
+ UnresolvedType paOrT2,
290
+ FloatingRequirementSource Source,
291
+ UnresolvedHandlingKind unresolvedHandling);
253
292
254
293
// / \brief Add a new same-type requirement between two unresolved types.
255
294
// /
256
295
// / The types are resolved with \c GenericSignatureBuilder::resolve. \c
257
296
// / diagnoseMismatch is called if the two types refer to incompatible concrete
258
297
// / types.
259
- bool
298
+ ConstraintResult
260
299
addSameTypeRequirement (UnresolvedType paOrT1, UnresolvedType paOrT2,
261
300
FloatingRequirementSource Source,
301
+ UnresolvedHandlingKind unresolvedHandling,
262
302
llvm::function_ref<void (Type, Type)> diagnoseMismatch);
263
303
264
304
// / Update the superclass for the equivalence class of \c T.
265
305
// /
266
- // / This assumes that the constraint has already been recorded
267
- bool updateSuperclass (PotentialArchetype *T,
306
+ // / This assumes that the constraint has already been recorded.
307
+ void updateSuperclass (PotentialArchetype *T,
268
308
Type superclass,
269
309
const RequirementSource *source);
270
310
271
311
private:
272
312
// / \brief Add a new superclass requirement specifying that the given
273
313
// / potential archetype has the given type as an ancestor.
274
- bool addSuperclassRequirementDirect (PotentialArchetype *T,
275
- Type Superclass,
276
- const RequirementSource *Source);
314
+ ConstraintResult addSuperclassRequirementDirect (
315
+ PotentialArchetype *T,
316
+ Type Superclass,
317
+ const RequirementSource *Source);
277
318
278
319
// / \brief Add a new type requirement specifying that the given
279
320
// / type conforms-to or is a superclass of the second type.
280
- bool addTypeRequirement (UnresolvedType subject,
321
+ ConstraintResult addTypeRequirement (
322
+ UnresolvedType subject,
281
323
UnresolvedType constraint,
282
324
FloatingRequirementSource source,
325
+ UnresolvedHandlingKind unresolvedHandling,
283
326
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited
284
327
= nullptr );
285
328
286
329
// / \brief Add a new conformance requirement specifying that the given
287
330
// / potential archetypes are equivalent.
288
- bool addSameTypeRequirementBetweenArchetypes (PotentialArchetype *T1,
331
+ ConstraintResult addSameTypeRequirementBetweenArchetypes (
332
+ PotentialArchetype *T1,
289
333
PotentialArchetype *T2,
290
334
const RequirementSource *Source);
291
335
292
336
// / \brief Add a new conformance requirement specifying that the given
293
337
// / potential archetype is bound to a concrete type.
294
- bool addSameTypeRequirementToConcrete (PotentialArchetype *T,
338
+ ConstraintResult addSameTypeRequirementToConcrete (PotentialArchetype *T,
295
339
Type Concrete,
296
340
const RequirementSource *Source);
297
341
@@ -300,26 +344,30 @@ class GenericSignatureBuilder {
300
344
// /
301
345
// / \param diagnoseMismatch Callback invoked when the types in the same-type
302
346
// / requirement mismatch.
303
- bool addSameTypeRequirementBetweenConcrete (
347
+ ConstraintResult addSameTypeRequirementBetweenConcrete (
304
348
Type T1, Type T2, FloatingRequirementSource Source,
305
349
llvm::function_ref<void (Type, Type)> diagnoseMismatch);
306
350
307
351
// / \brief Add a new layout requirement directly on the potential archetype.
308
352
// /
309
353
// / \returns true if this requirement makes the set of requirements
310
354
// / inconsistent, in which case a diagnostic will have been issued.
311
- bool addLayoutRequirementDirect (PotentialArchetype *PAT,
312
- LayoutConstraint Layout,
313
- const RequirementSource *Source);
355
+ ConstraintResult addLayoutRequirementDirect (PotentialArchetype *PAT,
356
+ LayoutConstraint Layout,
357
+ const RequirementSource *Source);
314
358
315
359
// / Add a new layout requirement to the subject.
316
- bool addLayoutRequirement (UnresolvedType subject,
317
- LayoutConstraint layout,
318
- FloatingRequirementSource source);
360
+ ConstraintResult addLayoutRequirement (
361
+ UnresolvedType subject,
362
+ LayoutConstraint layout,
363
+ FloatingRequirementSource source,
364
+ UnresolvedHandlingKind unresolvedHandling);
319
365
320
366
// / Add the requirements placed on the given type parameter
321
367
// / to the given potential archetype.
322
- bool addInheritedRequirements (TypeDecl *decl, PotentialArchetype *pa,
368
+ ConstraintResult addInheritedRequirements (
369
+ TypeDecl *decl,
370
+ PotentialArchetype *pa,
323
371
const RequirementSource *parentSource,
324
372
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited);
325
373
@@ -379,15 +427,15 @@ class GenericSignatureBuilder {
379
427
// /
380
428
// / \returns true if this requirement makes the set of requirements
381
429
// / inconsistent, in which case a diagnostic will have been issued.
382
- bool addRequirement (const RequirementRepr *req);
430
+ ConstraintResult addRequirement (const RequirementRepr *req);
383
431
384
432
// / \brief Add a new requirement.
385
433
// /
386
434
// / \returns true if this requirement makes the set of requirements
387
435
// / inconsistent, in which case a diagnostic will have been issued.
388
- bool addRequirement (const RequirementRepr *Req,
389
- FloatingRequirementSource source,
390
- const SubstitutionMap *subMap);
436
+ ConstraintResult addRequirement (const RequirementRepr *Req,
437
+ FloatingRequirementSource source,
438
+ const SubstitutionMap *subMap);
391
439
392
440
// / \brief Add an already-checked requirement.
393
441
// /
@@ -396,12 +444,15 @@ class GenericSignatureBuilder {
396
444
// /
397
445
// / \returns true if this requirement makes the set of requirements
398
446
// / inconsistent, in which case a diagnostic will have been issued.
399
- bool addRequirement (const Requirement &req, FloatingRequirementSource source,
400
- const SubstitutionMap *subMap = nullptr );
401
-
402
- bool addRequirement (const Requirement &req, FloatingRequirementSource source,
403
- const SubstitutionMap *subMap,
404
- llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
447
+ ConstraintResult addRequirement (const Requirement &req,
448
+ FloatingRequirementSource source,
449
+ const SubstitutionMap *subMap = nullptr );
450
+
451
+ ConstraintResult addRequirement (
452
+ const Requirement &req,
453
+ FloatingRequirementSource source,
454
+ const SubstitutionMap *subMap,
455
+ llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
405
456
406
457
// / \brief Add all of a generic signature's parameters and requirements.
407
458
void addGenericSignature (GenericSignature *sig);
@@ -454,6 +505,9 @@ class GenericSignatureBuilder {
454
505
ArrayRef<GenericTypeParamType *> genericParams);
455
506
456
507
private:
508
+ // / Process any delayed requirements that can be handled now.
509
+ void processDelayedRequirements ();
510
+
457
511
// / Describes the relationship between a given constraint and
458
512
// / the canonical constraint of the equivalence class.
459
513
enum class ConstraintRelation {
@@ -1519,6 +1573,28 @@ class GenericSignatureBuilder::PotentialArchetype {
1519
1573
friend class GenericSignatureBuilder ;
1520
1574
};
1521
1575
1576
+ // / Describes a requirement whose processing has been delayed for some reason.
1577
+ class GenericSignatureBuilder ::DelayedRequirement {
1578
+ public:
1579
+ RequirementKind kind;
1580
+ UnresolvedType lhs;
1581
+ RequirementRHS rhs;
1582
+ FloatingRequirementSource source;
1583
+ };
1584
+
1585
+ // / Whether the given constraint result signals an error.
1586
+ inline bool isErrorResult (GenericSignatureBuilder::ConstraintResult result) {
1587
+ switch (result) {
1588
+ case GenericSignatureBuilder::ConstraintResult::Concrete:
1589
+ case GenericSignatureBuilder::ConstraintResult::Conflicting:
1590
+ return true ;
1591
+
1592
+ case GenericSignatureBuilder::ConstraintResult::Resolved:
1593
+ case GenericSignatureBuilder::ConstraintResult::Unresolved:
1594
+ return false ;
1595
+ }
1596
+ }
1597
+
1522
1598
} // end namespace swift
1523
1599
1524
1600
#endif
0 commit comments