@@ -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;
@@ -651,37 +649,55 @@ class LifetimeDependenceChecker {
651
649
652
650
case ParsedLifetimeDependenceKind::Borrow: LLVM_FALLTHROUGH;
653
651
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
+ }
658
660
diagnose (loc,
659
- diag::lifetime_dependence_cannot_use_parsed_borrow_consuming ,
661
+ diag::lifetime_dependence_parsed_borrow_with_ownership ,
660
662
getNameForParsedLifetimeDependenceKind (parsedLifetimeKind),
661
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
+ }
662
679
return std::nullopt ;
663
680
}
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 (
677
692
loc,
678
693
diag::lifetime_dependence_cannot_use_default_escapable_consuming,
679
694
getOwnershipSpelling (loweredOwnership));
695
+ }
696
+ return std::nullopt ;
680
697
}
681
- return std::nullopt ;
698
+ return LifetimeDependenceKind::Inherit;
699
+ }
682
700
}
683
- return LifetimeDependenceKind::Inherit;
684
- }
685
701
}
686
702
687
703
// Finds the ParamDecl* and its index from a LifetimeDescriptor
0 commit comments