@@ -539,6 +539,23 @@ void RequirementFailure::maybeEmitRequirementNote(const Decl *anchor, Type lhs,
539539 return ;
540540 }
541541
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+
542559 if (req.getKind () == RequirementKind::Layout ||
543560 rhs->isEqual (req.getSecondType ())) {
544561 // If the note is tautological, bail out.
@@ -637,20 +654,6 @@ bool MissingConformanceFailure::diagnoseAsError() {
637654 if (diagnoseAsAmbiguousOperatorRef ())
638655 return true ;
639656
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-
654657 if (nonConformingType->isObjCExistentialType ()) {
655658 emitDiagnostic (diag::protocol_does_not_conform_static, nonConformingType,
656659 protocolType);
@@ -6348,111 +6351,6 @@ bool NotCompileTimeConstFailure::diagnoseAsError() {
63486351 return true ;
63496352}
63506353
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-
64566354bool InvalidPackElement::diagnoseAsError () {
64576355 emitDiagnostic (diag::each_non_pack, packElementType);
64586356 return true ;
0 commit comments