@@ -178,6 +178,20 @@ class GenericSignatureBuilder {
178
178
179
179
friend class RequirementSource ;
180
180
181
+ // / The result of introducing a new constraint.
182
+ enum class ConstraintResult {
183
+ // / The constraint was resolved and the relative potential archetypes
184
+ // / have been updated.
185
+ Resolved,
186
+
187
+ // / The constraint was written directly on a concrete type.
188
+ Concrete,
189
+
190
+ // / The constraint conflicted with existing constraints in some way;
191
+ // / the generic signature is ill-formed.
192
+ Conflicting,
193
+ };
194
+
181
195
private:
182
196
class InferRequirementsWalker ;
183
197
friend class InferRequirementsWalker ;
@@ -195,8 +209,8 @@ class GenericSignatureBuilder {
195
209
// / currently-unresolvable or nested type, this routine should be
196
210
// / called to record the unresolved requirement to be reconsidered later.
197
211
// /
198
- // / \returns false, which is used elsewhere to indicate "no failure" .
199
- bool recordUnresolvedRequirement (RequirementKind kind,
212
+ // / \returns ConstraintResult::Resolved .
213
+ ConstraintResult recordUnresolvedRequirement (RequirementKind kind,
200
214
UnresolvedType lhs,
201
215
RequirementRHS rhs,
202
216
FloatingRequirementSource source);
@@ -214,14 +228,15 @@ class GenericSignatureBuilder {
214
228
215
229
// / \brief Add a new conformance requirement specifying that the given
216
230
// / potential archetype conforms to the given protocol.
217
- bool addConformanceRequirement (PotentialArchetype *T,
218
- ProtocolDecl *Proto,
219
- const RequirementSource *Source);
231
+ ConstraintResult addConformanceRequirement (PotentialArchetype *T,
232
+ ProtocolDecl *Proto,
233
+ const RequirementSource *Source);
220
234
221
- bool addConformanceRequirement (PotentialArchetype *T,
222
- ProtocolDecl *Proto,
223
- const RequirementSource *Source,
224
- llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
235
+ ConstraintResult addConformanceRequirement (
236
+ PotentialArchetype *T,
237
+ ProtocolDecl *Proto,
238
+ const RequirementSource *Source,
239
+ llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
225
240
226
241
public:
227
242
// / \brief Add a new same-type requirement between two fully resolved types
@@ -231,7 +246,7 @@ class GenericSignatureBuilder {
231
246
// / incompatible (e.g. \c Foo<Bar<T>> and \c Foo<Baz>), \c diagnoseMismatch is
232
247
// / called with the two types that don't match (\c Bar<T> and \c Baz for the
233
248
// / previous example).
234
- bool
249
+ ConstraintResult
235
250
addSameTypeRequirementDirect (
236
251
ResolvedType paOrT1, ResolvedType paOrT2,
237
252
FloatingRequirementSource Source,
@@ -241,57 +256,63 @@ class GenericSignatureBuilder {
241
256
// / (output of GenericSignatureBuilder::resolve).
242
257
// /
243
258
// / The two types must not be incompatible concrete types.
244
- bool addSameTypeRequirementDirect (ResolvedType paOrT1, ResolvedType paOrT2,
245
- FloatingRequirementSource Source);
259
+ ConstraintResult addSameTypeRequirementDirect (
260
+ ResolvedType paOrT1,
261
+ ResolvedType paOrT2,
262
+ FloatingRequirementSource Source);
246
263
247
264
// / \brief Add a new same-type requirement between two unresolved types.
248
265
// /
249
266
// / The types are resolved with \c GenericSignatureBuilder::resolve, and must
250
267
// / not be incompatible concrete types.
251
- bool addSameTypeRequirement (UnresolvedType paOrT1, UnresolvedType paOrT2,
252
- FloatingRequirementSource Source);
268
+ ConstraintResult addSameTypeRequirement (UnresolvedType paOrT1,
269
+ UnresolvedType paOrT2,
270
+ FloatingRequirementSource Source);
253
271
254
272
// / \brief Add a new same-type requirement between two unresolved types.
255
273
// /
256
274
// / The types are resolved with \c GenericSignatureBuilder::resolve. \c
257
275
// / diagnoseMismatch is called if the two types refer to incompatible concrete
258
276
// / types.
259
- bool
277
+ ConstraintResult
260
278
addSameTypeRequirement (UnresolvedType paOrT1, UnresolvedType paOrT2,
261
279
FloatingRequirementSource Source,
262
280
llvm::function_ref<void (Type, Type)> diagnoseMismatch);
263
281
264
282
// / Update the superclass for the equivalence class of \c T.
265
283
// /
266
- // / This assumes that the constraint has already been recorded
267
- bool updateSuperclass (PotentialArchetype *T,
284
+ // / This assumes that the constraint has already been recorded.
285
+ void updateSuperclass (PotentialArchetype *T,
268
286
Type superclass,
269
287
const RequirementSource *source);
270
288
271
289
private:
272
290
// / \brief Add a new superclass requirement specifying that the given
273
291
// / potential archetype has the given type as an ancestor.
274
- bool addSuperclassRequirementDirect (PotentialArchetype *T,
275
- Type Superclass,
276
- const RequirementSource *Source);
292
+ ConstraintResult addSuperclassRequirementDirect (
293
+ PotentialArchetype *T,
294
+ Type Superclass,
295
+ const RequirementSource *Source);
277
296
278
297
// / \brief Add a new type requirement specifying that the given
279
298
// / type conforms-to or is a superclass of the second type.
280
- bool addTypeRequirement (UnresolvedType subject,
299
+ ConstraintResult addTypeRequirement (
300
+ UnresolvedType subject,
281
301
UnresolvedType constraint,
282
302
FloatingRequirementSource source,
283
303
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited
284
304
= nullptr );
285
305
286
306
// / \brief Add a new conformance requirement specifying that the given
287
307
// / potential archetypes are equivalent.
288
- bool addSameTypeRequirementBetweenArchetypes (PotentialArchetype *T1,
308
+ ConstraintResult addSameTypeRequirementBetweenArchetypes (
309
+ PotentialArchetype *T1,
289
310
PotentialArchetype *T2,
290
311
const RequirementSource *Source);
291
312
292
313
// / \brief Add a new conformance requirement specifying that the given
293
314
// / potential archetype is bound to a concrete type.
294
- bool addSameTypeRequirementToConcrete (PotentialArchetype *T,
315
+ ConstraintResult addSameTypeRequirementToConcrete (PotentialArchetype *T,
295
316
Type Concrete,
296
317
const RequirementSource *Source);
297
318
@@ -300,26 +321,28 @@ class GenericSignatureBuilder {
300
321
// /
301
322
// / \param diagnoseMismatch Callback invoked when the types in the same-type
302
323
// / requirement mismatch.
303
- bool addSameTypeRequirementBetweenConcrete (
324
+ ConstraintResult addSameTypeRequirementBetweenConcrete (
304
325
Type T1, Type T2, FloatingRequirementSource Source,
305
326
llvm::function_ref<void (Type, Type)> diagnoseMismatch);
306
327
307
328
// / \brief Add a new layout requirement directly on the potential archetype.
308
329
// /
309
330
// / \returns true if this requirement makes the set of requirements
310
331
// / inconsistent, in which case a diagnostic will have been issued.
311
- bool addLayoutRequirementDirect (PotentialArchetype *PAT,
312
- LayoutConstraint Layout,
313
- const RequirementSource *Source);
332
+ ConstraintResult addLayoutRequirementDirect (PotentialArchetype *PAT,
333
+ LayoutConstraint Layout,
334
+ const RequirementSource *Source);
314
335
315
336
// / Add a new layout requirement to the subject.
316
- bool addLayoutRequirement (UnresolvedType subject,
317
- LayoutConstraint layout,
318
- FloatingRequirementSource source);
337
+ ConstraintResult addLayoutRequirement (UnresolvedType subject,
338
+ LayoutConstraint layout,
339
+ FloatingRequirementSource source);
319
340
320
341
// / Add the requirements placed on the given type parameter
321
342
// / to the given potential archetype.
322
- bool addInheritedRequirements (TypeDecl *decl, PotentialArchetype *pa,
343
+ ConstraintResult addInheritedRequirements (
344
+ TypeDecl *decl,
345
+ PotentialArchetype *pa,
323
346
const RequirementSource *parentSource,
324
347
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited);
325
348
@@ -379,15 +402,15 @@ class GenericSignatureBuilder {
379
402
// /
380
403
// / \returns true if this requirement makes the set of requirements
381
404
// / inconsistent, in which case a diagnostic will have been issued.
382
- bool addRequirement (const RequirementRepr *req);
405
+ ConstraintResult addRequirement (const RequirementRepr *req);
383
406
384
407
// / \brief Add a new requirement.
385
408
// /
386
409
// / \returns true if this requirement makes the set of requirements
387
410
// / inconsistent, in which case a diagnostic will have been issued.
388
- bool addRequirement (const RequirementRepr *Req,
389
- FloatingRequirementSource source,
390
- const SubstitutionMap *subMap);
411
+ ConstraintResult addRequirement (const RequirementRepr *Req,
412
+ FloatingRequirementSource source,
413
+ const SubstitutionMap *subMap);
391
414
392
415
// / \brief Add an already-checked requirement.
393
416
// /
@@ -396,12 +419,15 @@ class GenericSignatureBuilder {
396
419
// /
397
420
// / \returns true if this requirement makes the set of requirements
398
421
// / 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);
422
+ ConstraintResult addRequirement (const Requirement &req,
423
+ FloatingRequirementSource source,
424
+ const SubstitutionMap *subMap = nullptr );
425
+
426
+ ConstraintResult addRequirement (
427
+ const Requirement &req,
428
+ FloatingRequirementSource source,
429
+ const SubstitutionMap *subMap,
430
+ llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
405
431
406
432
// / \brief Add all of a generic signature's parameters and requirements.
407
433
void addGenericSignature (GenericSignature *sig);
@@ -1519,6 +1545,18 @@ class GenericSignatureBuilder::PotentialArchetype {
1519
1545
friend class GenericSignatureBuilder ;
1520
1546
};
1521
1547
1548
+ // / Whether the given constraint result signals an error.
1549
+ inline bool isErrorResult (GenericSignatureBuilder::ConstraintResult result) {
1550
+ switch (result) {
1551
+ case GenericSignatureBuilder::ConstraintResult::Concrete:
1552
+ case GenericSignatureBuilder::ConstraintResult::Conflicting:
1553
+ return true ;
1554
+
1555
+ case GenericSignatureBuilder::ConstraintResult::Resolved:
1556
+ return false ;
1557
+ }
1558
+ }
1559
+
1522
1560
} // end namespace swift
1523
1561
1524
1562
#endif
0 commit comments