@@ -539,6 +539,23 @@ void RequirementFailure::maybeEmitRequirementNote(const Decl *anchor, Type lhs,
539
539
return ;
540
540
}
541
541
542
+ // If a requirement 'T: InvertibleProtocol' wasn't satisfied, then emit a note
543
+ // explaining that this requirement was implicit, but is suppressible.
544
+ if (req.getKind () == RequirementKind::Conformance &&
545
+ req.getProtocolDecl ()->getInvertibleProtocolKind () &&
546
+ req.getFirstType ()->is <SubstitutableType>()) {
547
+ auto diag = diag::noncopyable_generics_implicit_conformance_req;
548
+
549
+ // Handle 'some X' where the '& InvertibleProtocol' is implicit
550
+ if (auto substTy = req.getFirstType ()->getAs <GenericTypeParamType>())
551
+ if (auto gtpd = substTy->getDecl ())
552
+ if (gtpd->isOpaqueType ())
553
+ diag = diag::noncopyable_generics_implicit_composition;
554
+
555
+ emitDiagnosticAt (anchor, diag, req.getFirstType (), req.getSecondType ());
556
+ return ;
557
+ }
558
+
542
559
if (req.getKind () == RequirementKind::Layout ||
543
560
rhs->isEqual (req.getSecondType ())) {
544
561
// If the note is tautological, bail out.
@@ -637,20 +654,6 @@ bool MissingConformanceFailure::diagnoseAsError() {
637
654
if (diagnoseAsAmbiguousOperatorRef ())
638
655
return true ;
639
656
640
- // Use tailored diagnostics for failure to conform to Copyable.
641
- if (auto asProtoType = protocolType->getAs <ProtocolType>()) {
642
- if (auto *protoDecl = asProtoType->getDecl ()) {
643
- if (protoDecl->isSpecificProtocol (KnownProtocolKind::Copyable)) {
644
- NotCopyableFailure failure (getSolution (),
645
- nonConformingType,
646
- NoncopyableMatchFailure::forCopyableConstraint (),
647
- getLocator ());
648
- if (failure.diagnoseAsError ())
649
- return true ;
650
- }
651
- }
652
- }
653
-
654
657
if (nonConformingType->isObjCExistentialType ()) {
655
658
emitDiagnostic (diag::protocol_does_not_conform_static, nonConformingType,
656
659
protocolType);
@@ -6348,111 +6351,6 @@ bool NotCompileTimeConstFailure::diagnoseAsError() {
6348
6351
return true ;
6349
6352
}
6350
6353
6351
- bool NotCopyableFailure::diagnoseAsError () {
6352
- switch (failure.getKind ()) {
6353
- case NoncopyableMatchFailure::ExistentialCast: {
6354
- if (noncopyableTy->is <AnyMetatypeType>())
6355
- emitDiagnostic (diag::noncopyable_generics_metatype_cast,
6356
- noncopyableTy,
6357
- failure.getType (),
6358
- noncopyableTy->getMetatypeInstanceType ());
6359
- else
6360
- emitDiagnostic (diag::noncopyable_generics_erasure,
6361
- noncopyableTy,
6362
- failure.getType ());
6363
- return true ;
6364
- }
6365
-
6366
- case NoncopyableMatchFailure::CopyableConstraint: {
6367
- ConstraintLocator *loc = getLocator ();
6368
- auto path = loc->getPath ();
6369
-
6370
- if (loc->isLastElement <LocatorPathElt::AnyTupleElement>()) {
6371
- assert (!noncopyableTy->is <TupleType>() && " will use poor wording" );
6372
- emitDiagnostic (diag::tuple_move_only_not_supported, noncopyableTy);
6373
- return true ;
6374
- }
6375
-
6376
- if (loc->isLastElement <LocatorPathElt::PackElement>()) {
6377
- emitDiagnostic (diag::noncopyable_element_of_pack_not_supported,
6378
- noncopyableTy);
6379
- return true ;
6380
- }
6381
-
6382
- auto diagnoseGenericTypeParamType = [&](GenericTypeParamType *typeParam) {
6383
- if (!typeParam)
6384
- return false ;
6385
-
6386
- if (auto *paramDecl = typeParam->getDecl ()) {
6387
- if (auto *owningDecl =
6388
- dyn_cast_or_null<ValueDecl>(paramDecl->getDeclContext ()->getAsDecl ())) {
6389
-
6390
- // FIXME: these owningDecl names are kinda bad. like just `init(describing:)`
6391
- if (noncopyableTy->is <AnyMetatypeType>())
6392
- emitDiagnostic (diag::noncopyable_generics_generic_param_metatype,
6393
- noncopyableTy->getMetatypeInstanceType (),
6394
- paramDecl->getDescriptiveKind (),
6395
- typeParam,
6396
- owningDecl->getName (),
6397
- noncopyableTy);
6398
- else
6399
- emitDiagnostic (diag::noncopyable_generics_generic_param,
6400
- noncopyableTy,
6401
- paramDecl->getDescriptiveKind (),
6402
- typeParam,
6403
- owningDecl->getName ());
6404
-
6405
- // If we have a location for the parameter, point it out in a note.
6406
- if (auto loc = paramDecl->getNameLoc ()) {
6407
- emitDiagnosticAt (loc,
6408
- diag::noncopyable_generics_implicit_copyable,
6409
- paramDecl->getDescriptiveKind (),
6410
- typeParam);
6411
- }
6412
-
6413
- return true ;
6414
- }
6415
- }
6416
- return false ;
6417
- };
6418
-
6419
- // NOTE: a non-requirement constraint locator might now be impossible.
6420
- if (diagnoseGenericTypeParamType (loc->getGenericParameter ()))
6421
- return true ;
6422
-
6423
- if (auto tpr =
6424
- loc->getLastElementAs <LocatorPathElt::TypeParameterRequirement>()) {
6425
- auto signature = path[path.size () - 2 ]
6426
- .castTo <LocatorPathElt::OpenedGeneric>()
6427
- .getSignature ();
6428
- auto requirement = signature.getRequirements ()[tpr->getIndex ()];
6429
- auto subject = requirement.getFirstType ();
6430
-
6431
- if (diagnoseGenericTypeParamType (subject->getAs <GenericTypeParamType>()))
6432
- return true ;
6433
- }
6434
-
6435
- if (loc->getLastElementAs <LocatorPathElt::ConditionalRequirement>())
6436
- return false ; // Allow MissingConformanceFailure to diagnose instead.
6437
-
6438
- break ;
6439
- }
6440
- } // end switch
6441
-
6442
- // emit catch-all diagnostic
6443
- emitDiagnostic (diag::noncopyable_generics, noncopyableTy);
6444
-
6445
- #ifndef NDEBUG
6446
- #pragma clang diagnostic push
6447
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
6448
- getLocator ()->dump (&getConstraintSystem ());
6449
- #pragma clang diagnostic pop
6450
- llvm_unreachable (" NoncopyableGenerics: vague diagnostic for locator" );
6451
- #endif
6452
-
6453
- return true ;
6454
- }
6455
-
6456
6354
bool InvalidPackElement::diagnoseAsError () {
6457
6355
emitDiagnostic (diag::each_non_pack, packElementType);
6458
6356
return true ;
0 commit comments