@@ -186,15 +186,18 @@ void LifetimeDependenceInfo::Profile(llvm::FoldingSetNodeID &ID) const {
186
186
}
187
187
}
188
188
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) {
192
191
if (isa<ConstructorDecl>(afd)) {
193
192
return ValueOwnership::Owned;
194
193
}
195
194
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 ());
198
201
return ValueOwnership::InOut;
199
202
}
200
203
}
@@ -565,17 +568,25 @@ class LifetimeDependenceChecker {
565
568
}
566
569
}
567
570
568
- bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
569
- ValueOwnership loweredOwnership ,
571
+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind,
572
+ ParamDecl *param ,
570
573
bool isInterfaceFile = false ) const {
571
574
if (kind == ParsedLifetimeDependenceKind::Inherit) {
572
575
return true ;
573
576
}
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
+
574
585
if (kind == ParsedLifetimeDependenceKind::Borrow) {
575
586
// An owned/consumed BitwiseCopyable value can be effectively borrowed
576
587
// 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)) {
579
590
return true ;
580
591
}
581
592
if (isInterfaceFile) {
@@ -588,21 +599,23 @@ class LifetimeDependenceChecker {
588
599
return loweredOwnership == ValueOwnership::InOut;
589
600
}
590
601
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 {
594
604
if (kind == LifetimeDependenceKind::Inherit) {
595
605
return true ;
596
606
}
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);
597
614
// Lifetime dependence always propagates through temporary BitwiseCopyable
598
615
// values, even if the dependence is scoped.
599
- if (isBitwiseCopyable (type , ctx)) {
616
+ if (isBitwiseCopyable (paramType , ctx)) {
600
617
return true ;
601
618
}
602
- auto loweredOwnership = ownership != ValueOwnership::Default
603
- ? ownership
604
- : getLoweredOwnership (afd);
605
-
606
619
assert (kind == LifetimeDependenceKind::Scope);
607
620
return loweredOwnership == ValueOwnership::Shared ||
608
621
loweredOwnership == ValueOwnership::InOut;
@@ -690,7 +703,7 @@ class LifetimeDependenceChecker {
690
703
auto ownership = paramDecl->getValueOwnership ();
691
704
auto loweredOwnership = ownership != ValueOwnership::Default
692
705
? ownership
693
- : getLoweredOwnership (afd);
706
+ : getLoweredOwnership (paramDecl, afd);
694
707
695
708
switch (parsedLifetimeKind) {
696
709
case ParsedLifetimeDependenceKind::Default: {
@@ -717,9 +730,7 @@ class LifetimeDependenceChecker {
717
730
case ParsedLifetimeDependenceKind::Inout: {
718
731
// @lifetime(borrow x) is valid only for borrowing parameters.
719
732
// @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,
723
734
isInterfaceFile ())) {
724
735
return LifetimeDependenceKind::Scope;
725
736
}
@@ -1039,8 +1050,7 @@ class LifetimeDependenceChecker {
1039
1050
}
1040
1051
// Infer based on ownership if possible for either explicit accessors or
1041
1052
// methods as long as they pass preceding ambiguity checks.
1042
- auto kind = inferLifetimeDependenceKind (
1043
- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1053
+ auto kind = inferLifetimeDependenceKind (afd->getImplicitSelfDecl ());
1044
1054
if (!kind) {
1045
1055
// Special diagnostic for an attempt to depend on a consuming parameter.
1046
1056
diagnose (returnLoc,
@@ -1054,19 +1064,21 @@ class LifetimeDependenceChecker {
1054
1064
// Infer the kind of dependence that makes sense for reading or writing a
1055
1065
// stored property (for getters or initializers).
1056
1066
std::optional<LifetimeDependenceKind>
1057
- inferLifetimeDependenceKind (Type sourceType, ValueOwnership ownership ) {
1067
+ inferLifetimeDependenceKind (ParamDecl *param ) {
1058
1068
auto *afd = cast<AbstractFunctionDecl>(decl);
1059
- if (!sourceType->isEscapable ()) {
1069
+ Type paramType = param->getTypeInContext ();
1070
+ ValueOwnership ownership = param->getValueOwnership ();
1071
+ if (!paramType->isEscapable ()) {
1060
1072
return LifetimeDependenceKind::Inherit;
1061
1073
}
1062
1074
// Lifetime dependence always propagates through temporary BitwiseCopyable
1063
1075
// values, even if the dependence is scoped.
1064
- if (isBitwiseCopyable (sourceType , ctx)) {
1076
+ if (isBitwiseCopyable (paramType , ctx)) {
1065
1077
return LifetimeDependenceKind::Scope;
1066
1078
}
1067
1079
auto loweredOwnership = ownership != ValueOwnership::Default
1068
1080
? ownership
1069
- : getLoweredOwnership (afd);
1081
+ : getLoweredOwnership (param, afd);
1070
1082
// It is impossible to depend on a consumed Escapable value (unless it is
1071
1083
// BitwiseCopyable as checked above).
1072
1084
if (loweredOwnership == ValueOwnership::Owned) {
@@ -1114,8 +1126,7 @@ class LifetimeDependenceChecker {
1114
1126
return ;
1115
1127
}
1116
1128
// A single Escapable parameter must be borrowed.
1117
- auto kind = inferLifetimeDependenceKind (paramTypeInContext,
1118
- param->getValueOwnership ());
1129
+ auto kind = inferLifetimeDependenceKind (param);
1119
1130
if (!kind) {
1120
1131
diagnose (returnLoc,
1121
1132
diag::lifetime_dependence_cannot_infer_scope_ownership,
@@ -1172,9 +1183,7 @@ class LifetimeDependenceChecker {
1172
1183
return ;
1173
1184
}
1174
1185
auto kind = LifetimeDependenceKind::Scope;
1175
- auto paramOwnership = param->getValueOwnership ();
1176
- if (!isCompatibleWithOwnership (kind, paramTypeInContext, paramOwnership))
1177
- {
1186
+ if (!isCompatibleWithOwnership (kind, param)) {
1178
1187
diagnose (returnLoc,
1179
1188
diag::lifetime_dependence_cannot_infer_scope_ownership,
1180
1189
param->getParameterName ().str (), diagnosticQualifier ());
@@ -1207,8 +1216,7 @@ class LifetimeDependenceChecker {
1207
1216
}
1208
1217
}
1209
1218
1210
- candidateLifetimeKind =
1211
- inferLifetimeDependenceKind (paramTypeInContext, paramOwnership);
1219
+ candidateLifetimeKind = inferLifetimeDependenceKind (param);
1212
1220
if (!candidateLifetimeKind) {
1213
1221
continue ;
1214
1222
}
@@ -1383,11 +1391,9 @@ class LifetimeDependenceChecker {
1383
1391
}
1384
1392
}
1385
1393
}
1386
- auto *afd = cast<AbstractFunctionDecl>(decl);
1387
1394
// Either a Get or Modify without any wrapped accessor. Handle these like a
1388
1395
// read of the stored property.
1389
- return inferLifetimeDependenceKind (
1390
- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1396
+ return inferLifetimeDependenceKind (accessor->getImplicitSelfDecl ());
1391
1397
}
1392
1398
1393
1399
// Infer 'inout' parameter dependency when the only parameter is
0 commit comments