@@ -504,20 +504,18 @@ class LifetimeDependenceChecker {
504
504
}
505
505
506
506
bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
507
- ValueOwnership ownership ,
507
+ ValueOwnership loweredOwnership ,
508
508
bool isInterfaceFile = false ) const {
509
509
if (kind == ParsedLifetimeDependenceKind::Inherit) {
510
510
return true ;
511
511
}
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
-
520
512
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
+ }
521
519
if (isInterfaceFile) {
522
520
return loweredOwnership == ValueOwnership::Shared ||
523
521
loweredOwnership == ValueOwnership::InOut;
@@ -653,26 +651,42 @@ class LifetimeDependenceChecker {
653
651
case ParsedLifetimeDependenceKind::Inout: {
654
652
// @lifetime(borrow x) is valid only for borrowing parameters.
655
653
// @lifetime(&x) is valid only for inout parameters.
656
- if (!isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
657
- isInterfaceFile ())) {
658
- diagnose (
659
- loc,
660
- diag::lifetime_dependence_cannot_use_parsed_borrow_consuming,
661
- getNameForParsedLifetimeDependenceKind (parsedLifetimeKind),
662
- getOwnershipSpelling (loweredOwnership));
663
- return std::nullopt;
654
+ auto loweredOwnership = ownership != ValueOwnership::Default
655
+ ? ownership : getLoweredOwnership (afd);
656
+ if (isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
657
+ isInterfaceFile ())) {
658
+ return LifetimeDependenceKind::Scope;
664
659
}
665
- return LifetimeDependenceKind::Scope;
660
+ diagnose (loc,
661
+ diag::lifetime_dependence_parsed_borrow_with_ownership,
662
+ getNameForParsedLifetimeDependenceKind (parsedLifetimeKind),
663
+ 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
+ }
679
+ return std::nullopt;
666
680
}
667
681
case ParsedLifetimeDependenceKind::Inherit: {
668
682
// @lifetime(copy x) is only invalid for Escapable types.
669
683
if (type->isEscapable ()) {
670
684
if (loweredOwnership == ValueOwnership::Shared) {
671
685
diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
672
- descriptor.getString (), " borrow " );
686
+ " borrow " , descriptor.getString ());
673
687
} else if (loweredOwnership == ValueOwnership::InOut) {
674
688
diagnose (loc, diag::lifetime_dependence_invalid_inherit_escapable_type,
675
- descriptor.getString (), " & " );
689
+ " & " , descriptor.getString ());
676
690
} else {
677
691
diagnose (
678
692
loc,
0 commit comments