@@ -173,7 +173,7 @@ using namespace rewriting;
173
173
// / Desugar a same-type requirement that possibly has concrete types on either
174
174
// / side into a series of same-type and concrete-type requirements where the
175
175
// / left hand side is always a type parameter.
176
- static void desugarSameTypeRequirement (Type lhs, Type rhs , SourceLoc loc,
176
+ static void desugarSameTypeRequirement (Requirement req , SourceLoc loc,
177
177
SmallVectorImpl<Requirement> &result,
178
178
SmallVectorImpl<RequirementError> &errors) {
179
179
class Matcher : public TypeMatcher <Matcher> {
@@ -183,7 +183,6 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs, SourceLoc loc,
183
183
184
184
public:
185
185
bool recordedErrors = false ;
186
- bool recordedRequirements = false ;
187
186
188
187
explicit Matcher (SourceLoc loc,
189
188
SmallVectorImpl<Requirement> &result,
@@ -206,21 +205,18 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs, SourceLoc loc,
206
205
if (firstType->isTypeParameter () && secondType->isTypeParameter ()) {
207
206
result.emplace_back (RequirementKind::SameType,
208
207
sugaredFirstType, secondType);
209
- recordedRequirements = true ;
210
208
return true ;
211
209
}
212
210
213
211
if (firstType->isTypeParameter ()) {
214
212
result.emplace_back (RequirementKind::SameType,
215
213
sugaredFirstType, secondType);
216
- recordedRequirements = true ;
217
214
return true ;
218
215
}
219
216
220
217
if (secondType->isTypeParameter ()) {
221
218
result.emplace_back (RequirementKind::SameType,
222
219
secondType, sugaredFirstType);
223
- recordedRequirements = true ;
224
220
return true ;
225
221
}
226
222
@@ -231,149 +227,138 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs, SourceLoc loc,
231
227
}
232
228
} matcher (loc, result, errors);
233
229
234
- (void ) matcher.match (lhs, rhs );
230
+ (void ) matcher.match (req. getFirstType (), req. getSecondType () );
235
231
236
232
// If neither side is directly a type parameter, the type parameter
237
233
// must be in structural position where the enclosing type is redundant.
238
- if (!lhs->isTypeParameter () && !rhs->isTypeParameter () &&
234
+ if (!req.getFirstType ()->isTypeParameter () &&
235
+ !req.getSecondType ()->isTypeParameter () &&
239
236
!matcher.recordedErrors ) {
240
237
// FIXME: Add a tailored error message when requirements were
241
238
// recorded, e.g. Array<Int> == Array<T>. The outer type is
242
239
// redundant, but the inner requirement T == Int is not.
243
- errors.push_back (RequirementError::forRedundantRequirement (
244
- {RequirementKind::SameType, lhs, rhs}, loc));
240
+ errors.push_back (RequirementError::forRedundantRequirement (req, loc));
245
241
}
246
242
}
247
243
248
- static void desugarSuperclassRequirement (Type subjectType,
249
- Type constraintType,
244
+ static void desugarSuperclassRequirement (Requirement req,
250
245
SourceLoc loc,
251
246
SmallVectorImpl<Requirement> &result,
252
247
SmallVectorImpl<RequirementError> &errors) {
253
- if (!subjectType->isTypeParameter ()) {
254
- Requirement requirement (RequirementKind::Superclass,
255
- subjectType, constraintType);
256
- if (constraintType->isExactSuperclassOf (subjectType)) {
257
- errors.push_back (
258
- RequirementError::forRedundantRequirement (requirement, loc));
259
- } else {
260
- errors.push_back (
261
- RequirementError::forInvalidRequirementSubject (requirement, loc));
262
- }
263
-
248
+ if (req.getFirstType ()->isTypeParameter ()) {
249
+ result.push_back (req);
264
250
return ;
265
251
}
266
252
267
- result.emplace_back (RequirementKind::Superclass, subjectType, constraintType);
253
+ if (req.getSecondType ()->isExactSuperclassOf (req.getFirstType ())) {
254
+ errors.push_back (RequirementError::forRedundantRequirement (req, loc));
255
+ } else {
256
+ errors.push_back (RequirementError::forInvalidRequirementSubject (req, loc));
257
+ }
268
258
}
269
259
270
- static void desugarLayoutRequirement (Type subjectType,
271
- LayoutConstraint layout,
260
+ static void desugarLayoutRequirement (Requirement req,
272
261
SourceLoc loc,
273
262
SmallVectorImpl<Requirement> &result,
274
263
SmallVectorImpl<RequirementError> &errors) {
275
- if (!subjectType->isTypeParameter ()) {
276
- Requirement requirement (RequirementKind::Layout,
277
- subjectType, layout);
278
- if (layout->isClass () && subjectType->isAnyClassReferenceType ()) {
279
- errors.push_back (
280
- RequirementError::forRedundantRequirement (requirement, loc));
281
- } else {
282
- errors.push_back (
283
- RequirementError::forInvalidRequirementSubject (requirement, loc));
284
- }
285
-
264
+ if (req.getFirstType ()->isTypeParameter ()) {
265
+ result.push_back (req);
286
266
return ;
287
267
}
288
268
289
- result.emplace_back (RequirementKind::Layout, subjectType, layout);
269
+ if (req.getLayoutConstraint ()->isClass () &&
270
+ req.getFirstType ()->isAnyClassReferenceType ()) {
271
+ errors.push_back (RequirementError::forRedundantRequirement (req, loc));
272
+ } else {
273
+ errors.push_back (RequirementError::forInvalidRequirementSubject (req, loc));
274
+ }
290
275
}
291
276
292
277
// / Desugar a protocol conformance requirement by splitting up protocol
293
278
// / compositions on the right hand side into conformance and superclass
294
279
// / requirements.
295
- static void desugarConformanceRequirement (Type subjectType, Type constraintType ,
280
+ static void desugarConformanceRequirement (Requirement req ,
296
281
SourceLoc loc,
297
282
SmallVectorImpl<Requirement> &result,
298
283
SmallVectorImpl<RequirementError> &errors) {
299
284
// Fast path.
300
- if (constraintType->is <ProtocolType>()) {
301
- if (!subjectType->isTypeParameter ()) {
302
- // Check if the subject type actually conforms.
303
- auto *protoDecl = constraintType->castTo <ProtocolType>()->getDecl ();
304
- auto *module = protoDecl->getParentModule ();
305
- auto conformance = module ->lookupConformance (
306
- subjectType, protoDecl, /* allowMissing=*/ true );
307
- if (conformance.isInvalid ()) {
308
- errors.push_back (RequirementError::forInvalidRequirementSubject (
309
- {RequirementKind::Conformance, subjectType, constraintType}, loc));
310
- return ;
311
- }
285
+ if (req.getSecondType ()->is <ProtocolType>()) {
286
+ if (req.getFirstType ()->isTypeParameter ()) {
287
+ result.push_back (req);
288
+ return ;
289
+ }
312
290
313
- errors.push_back (RequirementError::forRedundantRequirement (
314
- {RequirementKind::Conformance, subjectType, constraintType}, loc));
291
+ // Check if the subject type actually conforms.
292
+ auto *protoDecl = req.getProtocolDecl ();
293
+ auto *module = protoDecl->getParentModule ();
294
+ auto conformance = module ->lookupConformance (
295
+ req.getFirstType (), protoDecl, /* allowMissing=*/ true );
296
+ if (conformance.isInvalid ()) {
297
+ errors.push_back (RequirementError::forInvalidRequirementSubject (req, loc));
298
+ return ;
299
+ }
315
300
316
- if (conformance.isConcrete ()) {
317
- // Introduce conditional requirements if the conformance is concrete.
318
- for (auto req : conformance.getConcrete ()->getConditionalRequirements ()) {
319
- desugarRequirement (req, loc, result, errors);
320
- }
321
- }
301
+ errors.push_back (RequirementError::forRedundantRequirement (req, loc));
322
302
323
- return ;
303
+ if (conformance.isConcrete ()) {
304
+ // Introduce conditional requirements if the conformance is concrete.
305
+ for (auto condReq : conformance.getConcrete ()->getConditionalRequirements ()) {
306
+ desugarRequirement (condReq, loc, result, errors);
307
+ }
324
308
}
325
309
326
- result.emplace_back (RequirementKind::Conformance, subjectType,
327
- constraintType);
328
310
return ;
329
311
}
330
312
331
- if (auto *paramType = constraintType->getAs <ParameterizedProtocolType>()) {
332
- desugarConformanceRequirement (subjectType, paramType->getBaseType (),
333
- loc, result, errors);
334
-
313
+ if (auto *paramType = req.getSecondType ()->getAs <ParameterizedProtocolType>()) {
335
314
SmallVector<Requirement, 2 > reqs;
336
- paramType->getRequirements (subjectType, reqs);
315
+
316
+ reqs.emplace_back (RequirementKind::Conformance, req.getFirstType (),
317
+ paramType->getBaseType ());
318
+ paramType->getRequirements (req.getFirstType (), reqs);
337
319
338
320
for (const auto &req : reqs)
339
321
desugarRequirement (req, loc, result, errors);
340
322
341
323
return ;
342
324
}
343
325
344
- auto *compositionType = constraintType->castTo <ProtocolCompositionType>();
326
+ auto *compositionType = req.getSecondType ()->castTo <ProtocolCompositionType>();
327
+ SmallVector<Requirement, 2 > memberReqs;
345
328
if (compositionType->hasExplicitAnyObject ()) {
346
- desugarLayoutRequirement (subjectType,
347
- LayoutConstraint::getLayoutConstraint (
348
- LayoutConstraintKind::Class),
349
- loc, result, errors);
329
+ memberReqs.emplace_back (RequirementKind::Layout, req.getFirstType (),
330
+ LayoutConstraint::getLayoutConstraint (
331
+ LayoutConstraintKind::Class));
350
332
}
351
333
352
334
for (auto memberType : compositionType->getMembers ()) {
353
- if (memberType->isConstraintType ())
354
- desugarConformanceRequirement (subjectType, memberType,
355
- loc, result, errors);
356
- else
357
- desugarSuperclassRequirement (subjectType, memberType,
358
- loc, result, errors);
335
+ memberReqs.emplace_back (
336
+ memberType->isConstraintType ()
337
+ ? RequirementKind::Conformance
338
+ : RequirementKind::Superclass,
339
+ req.getFirstType (), memberType);
359
340
}
341
+
342
+ for (auto memberReq : memberReqs)
343
+ desugarRequirement (memberReq, loc, result, errors);
360
344
}
361
345
362
346
// / Desugar same-shape requirements by equating the shapes of the
363
347
// / root pack types, and diagnose shape requirements on non-pack
364
348
// / types.
365
- static void desugarSameShapeRequirement (Type lhs, Type rhs , SourceLoc loc,
349
+ static void desugarSameShapeRequirement (Requirement req , SourceLoc loc,
366
350
SmallVectorImpl<Requirement> &result,
367
351
SmallVectorImpl<RequirementError> &errors) {
368
352
// For now, only allow shape requirements directly between pack types.
369
- if (!lhs->isParameterPack () || !rhs->isParameterPack ()) {
353
+ if (!req.getFirstType ()->isParameterPack () ||
354
+ !req.getSecondType ()->isParameterPack ()) {
370
355
errors.push_back (RequirementError::forInvalidShapeRequirement (
371
- {RequirementKind::SameShape, lhs, rhs} , loc));
356
+ req , loc));
372
357
}
373
358
374
359
result.emplace_back (RequirementKind::SameShape,
375
- lhs ->getRootGenericParam (),
376
- rhs ->getRootGenericParam ());
360
+ req. getFirstType () ->getRootGenericParam (),
361
+ req. getSecondType () ->getRootGenericParam ());
377
362
}
378
363
379
364
// / Convert a requirement where the subject type might not be a type parameter,
@@ -384,32 +369,25 @@ void
384
369
swift::rewriting::desugarRequirement (Requirement req, SourceLoc loc,
385
370
SmallVectorImpl<Requirement> &result,
386
371
SmallVectorImpl<RequirementError> &errors) {
387
- auto firstType = req.getFirstType ();
388
-
389
372
switch (req.getKind ()) {
390
373
case RequirementKind::SameShape:
391
- desugarSameShapeRequirement (firstType, req.getSecondType (),
392
- loc, result, errors);
374
+ desugarSameShapeRequirement (req, loc, result, errors);
393
375
break ;
394
376
395
377
case RequirementKind::Conformance:
396
- desugarConformanceRequirement (firstType, req.getSecondType (),
397
- loc, result, errors);
378
+ desugarConformanceRequirement (req, loc, result, errors);
398
379
break ;
399
380
400
381
case RequirementKind::Superclass:
401
- desugarSuperclassRequirement (firstType, req.getSecondType (),
402
- loc, result, errors);
382
+ desugarSuperclassRequirement (req, loc, result, errors);
403
383
break ;
404
384
405
385
case RequirementKind::Layout:
406
- desugarLayoutRequirement (firstType, req.getLayoutConstraint (),
407
- loc, result, errors);
386
+ desugarLayoutRequirement (req, loc, result, errors);
408
387
break ;
409
388
410
389
case RequirementKind::SameType:
411
- desugarSameTypeRequirement (firstType, req.getSecondType (),
412
- loc, result, errors);
390
+ desugarSameTypeRequirement (req, loc, result, errors);
413
391
break ;
414
392
}
415
393
}
@@ -453,11 +431,11 @@ static void realizeTypeRequirement(DeclContext *dc,
453
431
}
454
432
455
433
if (constraintType->isConstraintType ()) {
456
- // Handle conformance requirements.
457
- desugarConformanceRequirement (subjectType, constraintType , loc, reqs, errors);
434
+ Requirement req (RequirementKind::Conformance, subjectType, constraintType);
435
+ desugarRequirement (req , loc, reqs, errors);
458
436
} else if (constraintType->getClassOrBoundGenericClass ()) {
459
- // Handle superclass requirements.
460
- desugarSuperclassRequirement (subjectType, constraintType , loc, reqs, errors);
437
+ Requirement req (RequirementKind::Superclass, subjectType, constraintType);
438
+ desugarRequirement (req , loc, reqs, errors);
461
439
} else {
462
440
errors.push_back (
463
441
RequirementError::forInvalidTypeRequirement (subjectType,
@@ -641,7 +619,6 @@ void swift::rewriting::realizeRequirement(
641
619
bool shouldInferRequirements,
642
620
SmallVectorImpl<StructuralRequirement> &result,
643
621
SmallVectorImpl<RequirementError> &errors) {
644
- auto firstType = req.getFirstType ();
645
622
auto loc = (reqRepr ? reqRepr->getSeparatorLoc () : SourceLoc ());
646
623
auto *moduleForInference = dc->getParentModule ();
647
624
@@ -651,7 +628,9 @@ void swift::rewriting::realizeRequirement(
651
628
652
629
case RequirementKind::Superclass:
653
630
case RequirementKind::Conformance: {
631
+ auto firstType = req.getFirstType ();
654
632
auto secondType = req.getSecondType ();
633
+
655
634
if (shouldInferRequirements) {
656
635
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr ()->getStartLoc ()
657
636
: SourceLoc ());
@@ -668,14 +647,14 @@ void swift::rewriting::realizeRequirement(
668
647
669
648
case RequirementKind::Layout: {
670
649
if (shouldInferRequirements) {
650
+ auto firstType = req.getFirstType ();
671
651
auto firstLoc = (reqRepr ? reqRepr->getSubjectRepr ()->getStartLoc ()
672
652
: SourceLoc ());
673
653
inferRequirements (firstType, firstLoc, moduleForInference, dc, result);
674
654
}
675
655
676
656
SmallVector<Requirement, 2 > reqs;
677
- desugarLayoutRequirement (firstType, req.getLayoutConstraint (),
678
- loc, reqs, errors);
657
+ desugarRequirement (req, loc, reqs, errors);
679
658
680
659
for (auto req : reqs)
681
660
result.push_back ({req, loc, /* wasInferred=*/ false });
@@ -684,20 +663,20 @@ void swift::rewriting::realizeRequirement(
684
663
}
685
664
686
665
case RequirementKind::SameType: {
687
- auto secondType = req.getSecondType ();
688
666
if (shouldInferRequirements) {
667
+ auto firstType = req.getFirstType ();
689
668
auto firstLoc = (reqRepr ? reqRepr->getFirstTypeRepr ()->getStartLoc ()
690
669
: SourceLoc ());
691
670
inferRequirements (firstType, firstLoc, moduleForInference, dc, result);
692
671
672
+ auto secondType = req.getSecondType ();
693
673
auto secondLoc = (reqRepr ? reqRepr->getSecondTypeRepr ()->getStartLoc ()
694
674
: SourceLoc ());
695
675
inferRequirements (secondType, secondLoc, moduleForInference, dc, result);
696
676
}
697
677
698
678
SmallVector<Requirement, 2 > reqs;
699
- desugarSameTypeRequirement (req.getFirstType (), secondType, loc,
700
- reqs, errors);
679
+ desugarRequirement (req, loc, reqs, errors);
701
680
702
681
for (auto req : reqs)
703
682
result.push_back ({req, loc, /* wasInferred=*/ false });
@@ -928,8 +907,9 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
928
907
// An inferred same-type requirement between the two type declarations
929
908
// within this protocol or a protocol it inherits.
930
909
auto recordInheritedTypeRequirement = [&](TypeDecl *first, TypeDecl *second) {
931
- desugarSameTypeRequirement (getStructuralType (first),
932
- getStructuralType (second),
910
+ desugarRequirement (Requirement (RequirementKind::SameType,
911
+ getStructuralType (first),
912
+ getStructuralType (second)),
933
913
SourceLoc (), result, errors);
934
914
};
935
915
0 commit comments