Skip to content

Commit 1fdd569

Browse files
committed
Update callers of getLoweredOwnership() and add a test
1 parent c2836af commit 1fdd569

File tree

3 files changed

+52
-33
lines changed

3 files changed

+52
-33
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import AST
2323
import SIL
2424

25-
private let verbose = false
25+
private let verbose = true
2626

2727
private func log(prefix: Bool = true, _ message: @autoclosure () -> String) {
2828
if verbose {

lib/AST/LifetimeDependence.cpp

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

test/Sema/lifetime_attr.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,20 @@ struct Wrapper : ~Escapable {
125125
nonmutating _modify {// expected-error{{lifetime-dependent parameter 'self' must be 'inout'}}
126126
}
127127
}
128+
129+
var otherNE: NE {
130+
@_lifetime(copy self)
131+
get {
132+
_ne
133+
}
134+
@_lifetime(self: borrow newValue)
135+
set {
136+
self._ne = newValue
137+
}
138+
@_lifetime(&self)
139+
_modify {
140+
yield &self._ne
141+
}
142+
}
128143
}
144+

0 commit comments

Comments
 (0)