Skip to content

Commit 7ec4ed4

Browse files
committed
Add Sema diagnostic to ban _copy/_consume lifetime dependence on Escapable types
1 parent 5bf0a09 commit 7ec4ed4

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7832,6 +7832,9 @@ ERROR(lifetime_dependence_cannot_infer_no_candidates, none,
78327832
ERROR(lifetime_dependence_ctor_non_self_or_nil_return, none,
78337833
"expected nil or self as return values in an initializer with "
78347834
"lifetime dependent specifiers", ())
7835+
ERROR(lifetime_dependence_cannot_use_infer, none,
7836+
"invalid use of %0 lifetime dependence on Escapable type",
7837+
(StringRef))
78357838

78367839
//===----------------------------------------------------------------------===//
78377840
// MARK: Transferring

lib/Sema/LifetimeDependence.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
116116
SmallBitVector scopeLifetimeParamIndices(capacity);
117117

118118
auto updateLifetimeDependenceInfo = [&](LifetimeDependenceSpecifier specifier,
119-
unsigned paramIndexToSet,
119+
unsigned paramIndexToSet, Type type,
120120
ValueOwnership ownership) {
121121
auto loc = specifier.getLoc();
122122
auto kind = specifier.getLifetimeDependenceKind();
@@ -148,6 +148,14 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
148148
getOwnershipSpelling(ownership));
149149
return true;
150150
}
151+
if (kind == LifetimeDependenceKind::Consume ||
152+
kind == LifetimeDependenceKind::Copy) {
153+
if (type->isEscapable()) {
154+
diags.diagnose(loc, diag::lifetime_dependence_cannot_use_infer,
155+
specifier.getLifetimeDependenceKindString());
156+
return true;
157+
}
158+
}
151159
if (inheritLifetimeParamIndices.test(paramIndexToSet) ||
152160
scopeLifetimeParamIndices.test(paramIndexToSet)) {
153161
diags.diagnose(loc, diag::lifetime_dependence_duplicate_param_id);
@@ -168,17 +176,20 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
168176
switch (specifier.getSpecifierKind()) {
169177
case LifetimeDependenceSpecifier::SpecifierKind::Named: {
170178
bool foundParamName = false;
171-
unsigned paramIndexToSet = 1;
179+
unsigned paramIndex = 0;
172180
for (auto *param : *afd->getParameters()) {
173181
if (param->getParameterName() == specifier.getName()) {
174182
foundParamName = true;
175-
if (updateLifetimeDependenceInfo(specifier, paramIndexToSet,
176-
param->getValueOwnership())) {
183+
if (updateLifetimeDependenceInfo(
184+
specifier, paramIndex + 1,
185+
afd->mapTypeIntoContext(
186+
param->toFunctionParam().getParameterType()),
187+
param->getValueOwnership())) {
177188
return llvm::None;
178189
}
179190
break;
180191
}
181-
paramIndexToSet++;
192+
paramIndex++;
182193
}
183194
if (!foundParamName) {
184195
diags.diagnose(specifier.getLoc(),
@@ -189,29 +200,23 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
189200
break;
190201
}
191202
case LifetimeDependenceSpecifier::SpecifierKind::Ordered: {
192-
auto paramIndex = specifier.getIndex();
193-
if (paramIndex > afd->getParameters()->size()) {
203+
auto index = specifier.getIndex();
204+
if (index > afd->getParameters()->size()) {
194205
diags.diagnose(specifier.getLoc(),
195-
diag::lifetime_dependence_invalid_param_index,
196-
paramIndex);
206+
diag::lifetime_dependence_invalid_param_index, index);
197207
return llvm::None;
198208
}
199-
if (paramIndex == 0) {
200-
if (!afd->hasImplicitSelfDecl()) {
201-
diags.diagnose(specifier.getLoc(),
202-
diag::lifetime_dependence_invalid_self);
209+
if (index != 0) {
210+
auto param = afd->getParameters()->get(index - 1);
211+
auto ownership = param->getValueOwnership();
212+
auto type = afd->mapTypeIntoContext(
213+
param->toFunctionParam().getParameterType());
214+
if (updateLifetimeDependenceInfo(specifier, index, type, ownership)) {
203215
return llvm::None;
204216
}
217+
break;
205218
}
206-
auto ownership =
207-
paramIndex == 0
208-
? afd->getImplicitSelfDecl()->getValueOwnership()
209-
: afd->getParameters()->get(paramIndex - 1)->getValueOwnership();
210-
if (updateLifetimeDependenceInfo(
211-
specifier, /*paramIndexToSet*/ specifier.getIndex(), ownership)) {
212-
return llvm::None;
213-
}
214-
break;
219+
LLVM_FALLTHROUGH;
215220
}
216221
case LifetimeDependenceSpecifier::SpecifierKind::Self: {
217222
if (!afd->hasImplicitSelfDecl()) {
@@ -221,6 +226,7 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd, Type resultType,
221226
}
222227
if (updateLifetimeDependenceInfo(
223228
specifier, /*selfIndex*/ 0,
229+
afd->getImplicitSelfDecl()->getTypeInContext(),
224230
afd->getImplicitSelfDecl()->getValueOwnership())) {
225231
return llvm::None;
226232
}

0 commit comments

Comments
 (0)