@@ -568,17 +568,25 @@ class LifetimeDependenceChecker {
568568 }
569569 }
570570
571- bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
572- ValueOwnership loweredOwnership ,
571+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind,
572+ ParamDecl *param ,
573573 bool isInterfaceFile = false ) const {
574574 if (kind == ParsedLifetimeDependenceKind::Inherit) {
575575 return true ;
576576 }
577+
578+ auto *afd = cast<AbstractFunctionDecl>(decl);
579+ auto paramType = param->getTypeInContext ();
580+ auto ownership = param->getValueOwnership ();
581+ auto loweredOwnership = ownership != ValueOwnership::Default
582+ ? ownership
583+ : getLoweredOwnership (param, afd);
584+
577585 if (kind == ParsedLifetimeDependenceKind::Borrow) {
578586 // An owned/consumed BitwiseCopyable value can be effectively borrowed
579587 // because its lifetime can be indefinitely extended.
580- if (loweredOwnership == ValueOwnership::Owned
581- && isBitwiseCopyable (type , ctx)) {
588+ if (loweredOwnership == ValueOwnership::Owned &&
589+ isBitwiseCopyable (paramType , ctx)) {
582590 return true ;
583591 }
584592 if (isInterfaceFile) {
@@ -591,21 +599,23 @@ class LifetimeDependenceChecker {
591599 return loweredOwnership == ValueOwnership::InOut;
592600 }
593601
594- bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
595- ValueOwnership ownership) const {
596- auto *afd = cast<AbstractFunctionDecl>(decl);
602+ bool isCompatibleWithOwnership (LifetimeDependenceKind kind,
603+ ParamDecl *param) const {
597604 if (kind == LifetimeDependenceKind::Inherit) {
598605 return true ;
599606 }
607+
608+ auto *afd = cast<AbstractFunctionDecl>(decl);
609+ auto paramType = param->getTypeInContext ();
610+ auto ownership = param->getValueOwnership ();
611+ auto loweredOwnership = ownership != ValueOwnership::Default
612+ ? ownership
613+ : getLoweredOwnership (param, afd);
600614 // Lifetime dependence always propagates through temporary BitwiseCopyable
601615 // values, even if the dependence is scoped.
602- if (isBitwiseCopyable (type , ctx)) {
616+ if (isBitwiseCopyable (paramType , ctx)) {
603617 return true ;
604618 }
605- auto loweredOwnership = ownership != ValueOwnership::Default
606- ? ownership
607- : getLoweredOwnership (afd);
608-
609619 assert (kind == LifetimeDependenceKind::Scope);
610620 return loweredOwnership == ValueOwnership::Shared ||
611621 loweredOwnership == ValueOwnership::InOut;
@@ -693,7 +703,7 @@ class LifetimeDependenceChecker {
693703 auto ownership = paramDecl->getValueOwnership ();
694704 auto loweredOwnership = ownership != ValueOwnership::Default
695705 ? ownership
696- : getLoweredOwnership (afd);
706+ : getLoweredOwnership (paramDecl, afd);
697707
698708 switch (parsedLifetimeKind) {
699709 case ParsedLifetimeDependenceKind::Default: {
@@ -720,9 +730,7 @@ class LifetimeDependenceChecker {
720730 case ParsedLifetimeDependenceKind::Inout: {
721731 // @lifetime(borrow x) is valid only for borrowing parameters.
722732 // @lifetime(&x) is valid only for inout parameters.
723- auto loweredOwnership = ownership != ValueOwnership::Default
724- ? ownership : getLoweredOwnership (afd);
725- if (isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
733+ if (isCompatibleWithOwnership (parsedLifetimeKind, paramDecl,
726734 isInterfaceFile ())) {
727735 return LifetimeDependenceKind::Scope;
728736 }
@@ -1042,8 +1050,7 @@ class LifetimeDependenceChecker {
10421050 }
10431051 // Infer based on ownership if possible for either explicit accessors or
10441052 // methods as long as they pass preceding ambiguity checks.
1045- auto kind = inferLifetimeDependenceKind (
1046- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1053+ auto kind = inferLifetimeDependenceKind (afd->getImplicitSelfDecl ());
10471054 if (!kind) {
10481055 // Special diagnostic for an attempt to depend on a consuming parameter.
10491056 diagnose (returnLoc,
@@ -1057,19 +1064,21 @@ class LifetimeDependenceChecker {
10571064 // Infer the kind of dependence that makes sense for reading or writing a
10581065 // stored property (for getters or initializers).
10591066 std::optional<LifetimeDependenceKind>
1060- inferLifetimeDependenceKind (Type sourceType, ValueOwnership ownership ) {
1067+ inferLifetimeDependenceKind (ParamDecl *param ) {
10611068 auto *afd = cast<AbstractFunctionDecl>(decl);
1062- if (!sourceType->isEscapable ()) {
1069+ Type paramType = param->getTypeInContext ();
1070+ ValueOwnership ownership = param->getValueOwnership ();
1071+ if (!paramType->isEscapable ()) {
10631072 return LifetimeDependenceKind::Inherit;
10641073 }
10651074 // Lifetime dependence always propagates through temporary BitwiseCopyable
10661075 // values, even if the dependence is scoped.
1067- if (isBitwiseCopyable (sourceType , ctx)) {
1076+ if (isBitwiseCopyable (paramType , ctx)) {
10681077 return LifetimeDependenceKind::Scope;
10691078 }
10701079 auto loweredOwnership = ownership != ValueOwnership::Default
10711080 ? ownership
1072- : getLoweredOwnership (afd);
1081+ : getLoweredOwnership (param, afd);
10731082 // It is impossible to depend on a consumed Escapable value (unless it is
10741083 // BitwiseCopyable as checked above).
10751084 if (loweredOwnership == ValueOwnership::Owned) {
@@ -1117,8 +1126,7 @@ class LifetimeDependenceChecker {
11171126 return ;
11181127 }
11191128 // A single Escapable parameter must be borrowed.
1120- auto kind = inferLifetimeDependenceKind (paramTypeInContext,
1121- param->getValueOwnership ());
1129+ auto kind = inferLifetimeDependenceKind (param);
11221130 if (!kind) {
11231131 diagnose (returnLoc,
11241132 diag::lifetime_dependence_cannot_infer_scope_ownership,
@@ -1175,9 +1183,7 @@ class LifetimeDependenceChecker {
11751183 return ;
11761184 }
11771185 auto kind = LifetimeDependenceKind::Scope;
1178- auto paramOwnership = param->getValueOwnership ();
1179- if (!isCompatibleWithOwnership (kind, paramTypeInContext, paramOwnership))
1180- {
1186+ if (!isCompatibleWithOwnership (kind, param)) {
11811187 diagnose (returnLoc,
11821188 diag::lifetime_dependence_cannot_infer_scope_ownership,
11831189 param->getParameterName ().str (), diagnosticQualifier ());
@@ -1210,8 +1216,7 @@ class LifetimeDependenceChecker {
12101216 }
12111217 }
12121218
1213- candidateLifetimeKind =
1214- inferLifetimeDependenceKind (paramTypeInContext, paramOwnership);
1219+ candidateLifetimeKind = inferLifetimeDependenceKind (param);
12151220 if (!candidateLifetimeKind) {
12161221 continue ;
12171222 }
@@ -1386,11 +1391,9 @@ class LifetimeDependenceChecker {
13861391 }
13871392 }
13881393 }
1389- auto *afd = cast<AbstractFunctionDecl>(decl);
13901394 // Either a Get or Modify without any wrapped accessor. Handle these like a
13911395 // read of the stored property.
1392- return inferLifetimeDependenceKind (
1393- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1396+ return inferLifetimeDependenceKind (accessor->getImplicitSelfDecl ());
13941397 }
13951398
13961399 // Infer 'inout' parameter dependency when the only parameter is
0 commit comments