@@ -568,17 +568,25 @@ class LifetimeDependenceChecker {
568
568
}
569
569
}
570
570
571
- bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind, Type type,
572
- ValueOwnership loweredOwnership ,
571
+ bool isCompatibleWithOwnership (ParsedLifetimeDependenceKind kind,
572
+ ParamDecl *param ,
573
573
bool isInterfaceFile = false ) const {
574
574
if (kind == ParsedLifetimeDependenceKind::Inherit) {
575
575
return true ;
576
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
+
577
585
if (kind == ParsedLifetimeDependenceKind::Borrow) {
578
586
// An owned/consumed BitwiseCopyable value can be effectively borrowed
579
587
// 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)) {
582
590
return true ;
583
591
}
584
592
if (isInterfaceFile) {
@@ -591,21 +599,23 @@ class LifetimeDependenceChecker {
591
599
return loweredOwnership == ValueOwnership::InOut;
592
600
}
593
601
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 {
597
604
if (kind == LifetimeDependenceKind::Inherit) {
598
605
return true ;
599
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);
600
614
// Lifetime dependence always propagates through temporary BitwiseCopyable
601
615
// values, even if the dependence is scoped.
602
- if (isBitwiseCopyable (type , ctx)) {
616
+ if (isBitwiseCopyable (paramType , ctx)) {
603
617
return true ;
604
618
}
605
- auto loweredOwnership = ownership != ValueOwnership::Default
606
- ? ownership
607
- : getLoweredOwnership (afd);
608
-
609
619
assert (kind == LifetimeDependenceKind::Scope);
610
620
return loweredOwnership == ValueOwnership::Shared ||
611
621
loweredOwnership == ValueOwnership::InOut;
@@ -693,7 +703,7 @@ class LifetimeDependenceChecker {
693
703
auto ownership = paramDecl->getValueOwnership ();
694
704
auto loweredOwnership = ownership != ValueOwnership::Default
695
705
? ownership
696
- : getLoweredOwnership (afd);
706
+ : getLoweredOwnership (paramDecl, afd);
697
707
698
708
switch (parsedLifetimeKind) {
699
709
case ParsedLifetimeDependenceKind::Default: {
@@ -720,9 +730,7 @@ class LifetimeDependenceChecker {
720
730
case ParsedLifetimeDependenceKind::Inout: {
721
731
// @lifetime(borrow x) is valid only for borrowing parameters.
722
732
// @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,
726
734
isInterfaceFile ())) {
727
735
return LifetimeDependenceKind::Scope;
728
736
}
@@ -1042,8 +1050,7 @@ class LifetimeDependenceChecker {
1042
1050
}
1043
1051
// Infer based on ownership if possible for either explicit accessors or
1044
1052
// methods as long as they pass preceding ambiguity checks.
1045
- auto kind = inferLifetimeDependenceKind (
1046
- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1053
+ auto kind = inferLifetimeDependenceKind (afd->getImplicitSelfDecl ());
1047
1054
if (!kind) {
1048
1055
// Special diagnostic for an attempt to depend on a consuming parameter.
1049
1056
diagnose (returnLoc,
@@ -1057,19 +1064,21 @@ class LifetimeDependenceChecker {
1057
1064
// Infer the kind of dependence that makes sense for reading or writing a
1058
1065
// stored property (for getters or initializers).
1059
1066
std::optional<LifetimeDependenceKind>
1060
- inferLifetimeDependenceKind (Type sourceType, ValueOwnership ownership ) {
1067
+ inferLifetimeDependenceKind (ParamDecl *param ) {
1061
1068
auto *afd = cast<AbstractFunctionDecl>(decl);
1062
- if (!sourceType->isEscapable ()) {
1069
+ Type paramType = param->getTypeInContext ();
1070
+ ValueOwnership ownership = param->getValueOwnership ();
1071
+ if (!paramType->isEscapable ()) {
1063
1072
return LifetimeDependenceKind::Inherit;
1064
1073
}
1065
1074
// Lifetime dependence always propagates through temporary BitwiseCopyable
1066
1075
// values, even if the dependence is scoped.
1067
- if (isBitwiseCopyable (sourceType , ctx)) {
1076
+ if (isBitwiseCopyable (paramType , ctx)) {
1068
1077
return LifetimeDependenceKind::Scope;
1069
1078
}
1070
1079
auto loweredOwnership = ownership != ValueOwnership::Default
1071
1080
? ownership
1072
- : getLoweredOwnership (afd);
1081
+ : getLoweredOwnership (param, afd);
1073
1082
// It is impossible to depend on a consumed Escapable value (unless it is
1074
1083
// BitwiseCopyable as checked above).
1075
1084
if (loweredOwnership == ValueOwnership::Owned) {
@@ -1117,8 +1126,7 @@ class LifetimeDependenceChecker {
1117
1126
return ;
1118
1127
}
1119
1128
// A single Escapable parameter must be borrowed.
1120
- auto kind = inferLifetimeDependenceKind (paramTypeInContext,
1121
- param->getValueOwnership ());
1129
+ auto kind = inferLifetimeDependenceKind (param);
1122
1130
if (!kind) {
1123
1131
diagnose (returnLoc,
1124
1132
diag::lifetime_dependence_cannot_infer_scope_ownership,
@@ -1175,9 +1183,7 @@ class LifetimeDependenceChecker {
1175
1183
return ;
1176
1184
}
1177
1185
auto kind = LifetimeDependenceKind::Scope;
1178
- auto paramOwnership = param->getValueOwnership ();
1179
- if (!isCompatibleWithOwnership (kind, paramTypeInContext, paramOwnership))
1180
- {
1186
+ if (!isCompatibleWithOwnership (kind, param)) {
1181
1187
diagnose (returnLoc,
1182
1188
diag::lifetime_dependence_cannot_infer_scope_ownership,
1183
1189
param->getParameterName ().str (), diagnosticQualifier ());
@@ -1210,8 +1216,7 @@ class LifetimeDependenceChecker {
1210
1216
}
1211
1217
}
1212
1218
1213
- candidateLifetimeKind =
1214
- inferLifetimeDependenceKind (paramTypeInContext, paramOwnership);
1219
+ candidateLifetimeKind = inferLifetimeDependenceKind (param);
1215
1220
if (!candidateLifetimeKind) {
1216
1221
continue ;
1217
1222
}
@@ -1386,11 +1391,9 @@ class LifetimeDependenceChecker {
1386
1391
}
1387
1392
}
1388
1393
}
1389
- auto *afd = cast<AbstractFunctionDecl>(decl);
1390
1394
// Either a Get or Modify without any wrapped accessor. Handle these like a
1391
1395
// read of the stored property.
1392
- return inferLifetimeDependenceKind (
1393
- selfTypeInContext, afd->getImplicitSelfDecl ()->getValueOwnership ());
1396
+ return inferLifetimeDependenceKind (accessor->getImplicitSelfDecl ());
1394
1397
}
1395
1398
1396
1399
// Infer 'inout' parameter dependency when the only parameter is
0 commit comments