@@ -504,20 +504,18 @@ class LifetimeDependenceChecker {
504504 }
505505
506506 bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
507- ValueOwnership ownership ,
507+ ValueOwnership loweredOwnership ,
508508 bool isInterfaceFile = false ) const {
509509 if (kind == ParsedLifetimeDependenceKind::Inherit) {
510510 return true ;
511511 }
512- // Lifetime dependence always propagates through temporary BitwiseCopyable
513- // values, even if the dependence is scoped.
514- if (isBitwiseCopyable (type, ctx)) {
515- return true ;
516- }
517- auto loweredOwnership = ownership != ValueOwnership::Default
518- ? ownership : getLoweredOwnership (afd);
519-
520512 if (kind == ParsedLifetimeDependenceKind::Borrow) {
513+ // An owned/consumed BitwiseCopyable value can be effectively borrowed
514+ // because its lifetime can be indefinitely extended.
515+ if (loweredOwnership == ValueOwnership::Owned
516+ && isBitwiseCopyable (type, ctx)) {
517+ return true ;
518+ }
521519 if (isInterfaceFile) {
522520 return loweredOwnership == ValueOwnership::Shared ||
523521 loweredOwnership == ValueOwnership::InOut;
@@ -651,37 +649,55 @@ class LifetimeDependenceChecker {
651649
652650 case ParsedLifetimeDependenceKind::Borrow: LLVM_FALLTHROUGH;
653651 case ParsedLifetimeDependenceKind::Inout: {
654- // @lifetime(borrow x) is valid only for borrowing parameters.
655- // @lifetime(inout x) is valid only for inout parameters.
656- if (!isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
657- isInterfaceFile ())) {
652+ // @lifetime(borrow x) is valid only for borrowing parameters.
653+ // @lifetime(&x) is valid only for inout parameters.
654+ auto loweredOwnership = ownership != ValueOwnership::Default
655+ ? ownership : getLoweredOwnership (afd);
656+ if (isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
657+ isInterfaceFile ())) {
658+ return LifetimeDependenceKind::Scope;
659+ }
658660 diagnose (loc,
659- diag::lifetime_dependence_cannot_use_parsed_borrow_consuming ,
661+ diag::lifetime_dependence_parsed_borrow_with_ownership ,
660662 getNameForParsedLifetimeDependenceKind (parsedLifetimeKind),
661663 getOwnershipSpelling (loweredOwnership));
664+ switch (loweredOwnership) {
665+ case ValueOwnership::Shared:
666+ diagnose (loc,
667+ diag::lifetime_dependence_parsed_borrow_with_ownership_fix,
668+ " borrow " , descriptor.getString ());
669+ break ;
670+ case ValueOwnership::InOut:
671+ diagnose (loc,
672+ diag::lifetime_dependence_parsed_borrow_with_ownership_fix,
673+ " &" , descriptor.getString ());
674+ break ;
675+ case ValueOwnership::Owned:
676+ case ValueOwnership::Default:
677+ break ;
678+ }
662679 return std::nullopt ;
663680 }
664- return LifetimeDependenceKind::Scope;
665- }
666- case ParsedLifetimeDependenceKind::Inherit:
667- // @lifetime(copy x) is only invalid for Escapable types.
668- if (type->isEscapable ()) {
669- if (loweredOwnership == ValueOwnership::Shared) {
670- diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
671- descriptor.getString (), " borrow " );
672- } else if (loweredOwnership == ValueOwnership::InOut) {
673- diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
674- descriptor.getString (), " &" );
675- } else {
676- diagnose (
681+ case ParsedLifetimeDependenceKind::Inherit: {
682+ // @lifetime(copy x) is only invalid for Escapable types.
683+ if (type->isEscapable ()) {
684+ if (loweredOwnership == ValueOwnership::Shared) {
685+ diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
686+ " borrow " , descriptor.getString ());
687+ } else if (loweredOwnership == ValueOwnership::InOut) {
688+ diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
689+ " &" , descriptor.getString ());
690+ } else {
691+ diagnose (
677692 loc,
678693 diag::lifetime_dependence_cannot_use_default_escapable_consuming,
679694 getOwnershipSpelling (loweredOwnership));
695+ }
696+ return std::nullopt ;
680697 }
681- return std::nullopt ;
698+ return LifetimeDependenceKind::Inherit;
699+ }
682700 }
683- return LifetimeDependenceKind::Inherit;
684- }
685701 }
686702
687703 // Finds the ParamDecl* and its index from a LifetimeDescriptor
0 commit comments