@@ -229,7 +229,8 @@ swift::rewriting::desugarRequirement(Requirement req,
229
229
230
230
static void realizeTypeRequirement (Type subjectType, Type constraintType,
231
231
SourceLoc loc,
232
- SmallVectorImpl<StructuralRequirement> &result) {
232
+ SmallVectorImpl<StructuralRequirement> &result,
233
+ SmallVectorImpl<RequirementError> &errors) {
233
234
SmallVector<Requirement, 2 > reqs;
234
235
235
236
if (constraintType->isConstraintType ()) {
@@ -239,7 +240,10 @@ static void realizeTypeRequirement(Type subjectType, Type constraintType,
239
240
// Handle superclass requirements.
240
241
desugarSuperclassRequirement (subjectType, constraintType, reqs);
241
242
} else {
242
- // FIXME: Diagnose
243
+ errors.push_back (
244
+ RequirementError::forInvalidConformance (subjectType,
245
+ constraintType,
246
+ loc));
243
247
return ;
244
248
}
245
249
@@ -373,7 +377,8 @@ void swift::rewriting::inferRequirements(
373
377
void swift::rewriting::realizeRequirement (
374
378
Requirement req, RequirementRepr *reqRepr,
375
379
ModuleDecl *moduleForInference,
376
- SmallVectorImpl<StructuralRequirement> &result) {
380
+ SmallVectorImpl<StructuralRequirement> &result,
381
+ SmallVectorImpl<RequirementError> &errors) {
377
382
auto firstType = req.getFirstType ();
378
383
auto loc = (reqRepr ? reqRepr->getSeparatorLoc () : SourceLoc ());
379
384
@@ -391,7 +396,7 @@ void swift::rewriting::realizeRequirement(
391
396
inferRequirements (secondType, secondLoc, moduleForInference, result);
392
397
}
393
398
394
- realizeTypeRequirement (firstType, secondType, loc, result);
399
+ realizeTypeRequirement (firstType, secondType, loc, result, errors );
395
400
break ;
396
401
}
397
402
@@ -437,7 +442,8 @@ void swift::rewriting::realizeRequirement(
437
442
// / AssociatedTypeDecl or GenericTypeParamDecl.
438
443
void swift::rewriting::realizeInheritedRequirements (
439
444
TypeDecl *decl, Type type, ModuleDecl *moduleForInference,
440
- SmallVectorImpl<StructuralRequirement> &result) {
445
+ SmallVectorImpl<StructuralRequirement> &result,
446
+ SmallVectorImpl<RequirementError> &errors) {
441
447
auto &ctx = decl->getASTContext ();
442
448
auto inheritedTypes = decl->getInherited ();
443
449
@@ -455,7 +461,57 @@ void swift::rewriting::realizeInheritedRequirements(
455
461
inferRequirements (inheritedType, loc, moduleForInference, result);
456
462
}
457
463
458
- realizeTypeRequirement (type, inheritedType, loc, result);
464
+ realizeTypeRequirement (type, inheritedType, loc, result, errors);
465
+ }
466
+ }
467
+
468
+ void swift::rewriting::diagnoseRequirementErrors (
469
+ ASTContext &ctx, SmallVectorImpl<RequirementError> &errors,
470
+ bool allowConcreteGenericParams) {
471
+ if (ctx.LangOpts .RequirementMachineProtocolSignatures !=
472
+ RequirementMachineMode::Enabled)
473
+ return ;
474
+
475
+ for (auto error : errors) {
476
+ SourceLoc loc = error.loc ;
477
+
478
+ switch (error.kind ) {
479
+ case RequirementError::Kind::InvalidConformance: {
480
+ Type subjectType = error.invalidConformance .subjectType ;
481
+ Type constraint = error.invalidConformance .constraint ;
482
+
483
+ // FIXME: The constraint string is printed directly here because
484
+ // the current default is to not print `any` for existential
485
+ // types, but this error message is super confusing without `any`
486
+ // if the user wrote it explicitly.
487
+ PrintOptions options;
488
+ options.PrintExplicitAny = true ;
489
+ auto constraintString = constraint.getString (options);
490
+
491
+ ctx.Diags .diagnose (loc, diag::requires_conformance_nonprotocol,
492
+ subjectType, constraintString);
493
+
494
+ auto getNameWithoutSelf = [&](std::string subjectTypeName) {
495
+ std::string selfSubstring = " Self." ;
496
+
497
+ if (subjectTypeName.rfind (selfSubstring, 0 ) == 0 ) {
498
+ return subjectTypeName.erase (0 , selfSubstring.length ());
499
+ }
500
+
501
+ return subjectTypeName;
502
+ };
503
+
504
+ if (allowConcreteGenericParams) {
505
+ auto subjectTypeName = subjectType.getString ();
506
+ auto subjectTypeNameWithoutSelf = getNameWithoutSelf (subjectTypeName);
507
+ ctx.Diags .diagnose (loc, diag::requires_conformance_nonprotocol_fixit,
508
+ subjectTypeNameWithoutSelf, constraintString)
509
+ .fixItReplace (loc, " == " );
510
+ }
511
+
512
+ break ;
513
+ }
514
+ }
459
515
}
460
516
}
461
517
@@ -465,19 +521,22 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
465
521
assert (!proto->hasLazyRequirementSignature ());
466
522
467
523
SmallVector<StructuralRequirement, 4 > result;
524
+ SmallVector<RequirementError, 4 > errors;
468
525
469
526
auto &ctx = proto->getASTContext ();
470
527
471
528
auto selfTy = proto->getSelfInterfaceType ();
472
529
473
530
realizeInheritedRequirements (proto, selfTy,
474
- /* moduleForInference=*/ nullptr , result);
531
+ /* moduleForInference=*/ nullptr ,
532
+ result, errors);
475
533
476
534
// Add requirements from the protocol's own 'where' clause.
477
535
WhereClauseOwner (proto).visitRequirements (TypeResolutionStage::Structural,
478
536
[&](const Requirement &req, RequirementRepr *reqRepr) {
479
537
realizeRequirement (req, reqRepr,
480
- /* moduleForInference=*/ nullptr , result);
538
+ /* moduleForInference=*/ nullptr ,
539
+ result, errors);
481
540
return false ;
482
541
});
483
542
@@ -502,15 +561,15 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
502
561
auto assocType = assocTypeDecl->getDeclaredInterfaceType ();
503
562
realizeInheritedRequirements (assocTypeDecl, assocType,
504
563
/* moduleForInference=*/ nullptr ,
505
- result);
564
+ result, errors );
506
565
507
566
// Add requirements from this associated type's where clause.
508
567
WhereClauseOwner (assocTypeDecl).visitRequirements (
509
568
TypeResolutionStage::Structural,
510
569
[&](const Requirement &req, RequirementRepr *reqRepr) {
511
570
realizeRequirement (req, reqRepr,
512
571
/* moduleForInference=*/ nullptr ,
513
- result);
572
+ result, errors );
514
573
return false ;
515
574
});
516
575
}
0 commit comments