@@ -186,15 +186,18 @@ void LifetimeDependenceInfo::Profile(llvm::FoldingSetNodeID &ID) const {
186186 }
187187}
188188
189- // Warning: this is incorrect for Setter 'newValue' parameters. It should only
190- // be called for a Setter's 'self'.
191- static ValueOwnership getLoweredOwnership (AbstractFunctionDecl *afd) {
189+ static ValueOwnership getLoweredOwnership (ParamDecl *param,
190+ AbstractFunctionDecl *afd) {
192191 if (isa<ConstructorDecl>(afd)) {
193192 return ValueOwnership::Owned;
194193 }
195194 if (auto *ad = dyn_cast<AccessorDecl>(afd)) {
196- if (ad->getAccessorKind () == AccessorKind::Set ||
197- isYieldingMutableAccessor (ad->getAccessorKind ())) {
195+ if (ad->getAccessorKind () == AccessorKind::Set) {
196+ return param->isSelfParameter () ? ValueOwnership::InOut
197+ : ValueOwnership::Owned;
198+ }
199+ if (isYieldingMutableAccessor (ad->getAccessorKind ())) {
200+ assert (param->isSelfParameter ());
198201 return ValueOwnership::InOut;
199202 }
200203 }
@@ -565,17 +568,25 @@ class LifetimeDependenceChecker {
565568 }
566569 }
567570
568- bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
569- ValueOwnership loweredOwnership ,
571+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind,
572+ ParamDecl *param ,
570573 bool isInterfaceFile = false ) const {
571574 if (kind == ParsedLifetimeDependenceKind::Inherit) {
572575 return true ;
573576 }
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+
574585 if (kind == ParsedLifetimeDependenceKind::Borrow) {
575586 // An owned/consumed BitwiseCopyable value can be effectively borrowed
576587 // because its lifetime can be indefinitely extended.
577- if (loweredOwnership == ValueOwnership::Owned
578- && isBitwiseCopyable (type , ctx)) {
588+ if (loweredOwnership == ValueOwnership::Owned &&
589+ isBitwiseCopyable (paramType , ctx)) {
579590 return true ;
580591 }
581592 if (isInterfaceFile) {
@@ -588,21 +599,23 @@ class LifetimeDependenceChecker {
588599 return loweredOwnership == ValueOwnership::InOut;
589600 }
590601
591- bool isCompatibleWithOwnership (LifetimeDependenceKind kind, Type type,
592- ValueOwnership ownership) const {
593- auto *afd = cast<AbstractFunctionDecl>(decl);
602+ bool isCompatibleWithOwnership (LifetimeDependenceKind kind,
603+ ParamDecl *param) const {
594604 if (kind == LifetimeDependenceKind::Inherit) {
595605 return true ;
596606 }
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);
597614 // Lifetime dependence always propagates through temporary BitwiseCopyable
598615 // values, even if the dependence is scoped.
599- if (isBitwiseCopyable (type , ctx)) {
616+ if (isBitwiseCopyable (paramType , ctx)) {
600617 return true ;
601618 }
602- auto loweredOwnership = ownership != ValueOwnership::Default
603- ? ownership
604- : getLoweredOwnership (afd);
605-
606619 assert (kind == LifetimeDependenceKind::Scope);
607620 return loweredOwnership == ValueOwnership::Shared ||
608621 loweredOwnership == ValueOwnership::InOut;
@@ -690,7 +703,7 @@ class LifetimeDependenceChecker {
690703 auto ownership = paramDecl->getValueOwnership ();
691704 auto loweredOwnership = ownership != ValueOwnership::Default
692705 ? ownership
693- : getLoweredOwnership (afd);
706+ : getLoweredOwnership (paramDecl, afd);
694707
695708 switch (parsedLifetimeKind) {
696709 case ParsedLifetimeDependenceKind::Default: {
@@ -717,9 +730,7 @@ class LifetimeDependenceChecker {
717730 case ParsedLifetimeDependenceKind::Inout: {
718731 // @lifetime(borrow x) is valid only for borrowing parameters.
719732 // @lifetime(&x) is valid only for inout parameters.
720- auto loweredOwnership = ownership != ValueOwnership::Default
721- ? ownership : getLoweredOwnership (afd);
722- if (isCompatibleWithOwnership (parsedLifetimeKind, type, loweredOwnership,
733+ if (isCompatibleWithOwnership (parsedLifetimeKind, paramDecl,
723734 isInterfaceFile ())) {
724735 return LifetimeDependenceKind::Scope;
725736 }
@@ -1039,8 +1050,7 @@ class LifetimeDependenceChecker {
10391050 }
10401051 // Infer based on ownership if possible for either explicit accessors or
10411052 // methods as long as they pass preceding ambiguity checks.
1042- auto kind = inferLifetimeDependenceKind (
1043- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1053+ auto kind = inferLifetimeDependenceKind (afd->getImplicitSelfDecl ());
10441054 if (!kind) {
10451055 // Special diagnostic for an attempt to depend on a consuming parameter.
10461056 diagnose (returnLoc,
@@ -1054,19 +1064,21 @@ class LifetimeDependenceChecker {
10541064 // Infer the kind of dependence that makes sense for reading or writing a
10551065 // stored property (for getters or initializers).
10561066 std::optional<LifetimeDependenceKind>
1057- inferLifetimeDependenceKind (Type sourceType, ValueOwnership ownership ) {
1067+ inferLifetimeDependenceKind (ParamDecl *param ) {
10581068 auto *afd = cast<AbstractFunctionDecl>(decl);
1059- if (!sourceType->isEscapable ()) {
1069+ Type paramType = param->getTypeInContext ();
1070+ ValueOwnership ownership = param->getValueOwnership ();
1071+ if (!paramType->isEscapable ()) {
10601072 return LifetimeDependenceKind::Inherit;
10611073 }
10621074 // Lifetime dependence always propagates through temporary BitwiseCopyable
10631075 // values, even if the dependence is scoped.
1064- if (isBitwiseCopyable (sourceType , ctx)) {
1076+ if (isBitwiseCopyable (paramType , ctx)) {
10651077 return LifetimeDependenceKind::Scope;
10661078 }
10671079 auto loweredOwnership = ownership != ValueOwnership::Default
10681080 ? ownership
1069- : getLoweredOwnership (afd);
1081+ : getLoweredOwnership (param, afd);
10701082 // It is impossible to depend on a consumed Escapable value (unless it is
10711083 // BitwiseCopyable as checked above).
10721084 if (loweredOwnership == ValueOwnership::Owned) {
@@ -1114,8 +1126,7 @@ class LifetimeDependenceChecker {
11141126 return ;
11151127 }
11161128 // A single Escapable parameter must be borrowed.
1117- auto kind = inferLifetimeDependenceKind (paramTypeInContext,
1118- param->getValueOwnership ());
1129+ auto kind = inferLifetimeDependenceKind (param);
11191130 if (!kind) {
11201131 diagnose (returnLoc,
11211132 diag::lifetime_dependence_cannot_infer_scope_ownership,
@@ -1172,9 +1183,7 @@ class LifetimeDependenceChecker {
11721183 return ;
11731184 }
11741185 auto kind = LifetimeDependenceKind::Scope;
1175- auto paramOwnership = param->getValueOwnership ();
1176- if (!isCompatibleWithOwnership (kind, paramTypeInContext, paramOwnership))
1177- {
1186+ if (!isCompatibleWithOwnership (kind, param)) {
11781187 diagnose (returnLoc,
11791188 diag::lifetime_dependence_cannot_infer_scope_ownership,
11801189 param->getParameterName ().str (), diagnosticQualifier ());
@@ -1207,8 +1216,7 @@ class LifetimeDependenceChecker {
12071216 }
12081217 }
12091218
1210- candidateLifetimeKind =
1211- inferLifetimeDependenceKind (paramTypeInContext, paramOwnership);
1219+ candidateLifetimeKind = inferLifetimeDependenceKind (param);
12121220 if (!candidateLifetimeKind) {
12131221 continue ;
12141222 }
@@ -1383,11 +1391,9 @@ class LifetimeDependenceChecker {
13831391 }
13841392 }
13851393 }
1386- auto *afd = cast<AbstractFunctionDecl>(decl);
13871394 // Either a Get or Modify without any wrapped accessor. Handle these like a
13881395 // read of the stored property.
1389- return inferLifetimeDependenceKind (
1390- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1396+ return inferLifetimeDependenceKind (accessor->getImplicitSelfDecl ());
13911397 }
13921398
13931399 // Infer 'inout' parameter dependency when the only parameter is
0 commit comments