Skip to content

Commit d8c9d33

Browse files
committed
Diagnose multiple @Lifetime attributes with same target
1 parent 9c5810f commit d8c9d33

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7992,6 +7992,8 @@ ERROR(lifetime_dependence_invalid_inherit_escapable_type, none,
79927992
ERROR(lifetime_dependence_cannot_use_parsed_borrow_consuming, none,
79937993
"invalid use of borrow dependence with consuming ownership",
79947994
())
7995+
ERROR(lifetime_dependence_duplicate_target, none,
7996+
"invalid duplicate target lifetime dependencies on function", ())
79957997

79967998
//===----------------------------------------------------------------------===//
79977999
// MARK: Sending

lib/AST/LifetimeDependence.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,26 @@ populateLifetimeDependence(AbstractFunctionDecl *afd, LifetimeEntry *entry) {
376376

377377
std::optional<ArrayRef<LifetimeDependenceInfo>>
378378
LifetimeDependenceInfo::fromLifetimeAttribute(AbstractFunctionDecl *afd) {
379+
auto *dc = afd->getDeclContext();
380+
auto &ctx = dc->getASTContext();
381+
auto &diags = ctx.Diags;
382+
379383
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
384+
llvm::SmallSet<unsigned, 1> lifetimeDependentTargets;
380385
auto lifetimeAttrs = afd->getAttrs().getAttributes<LifetimeAttr>();
381386
for (auto attr : lifetimeAttrs) {
382387
auto lifetimeDependenceInfo =
383388
populateLifetimeDependence(afd, attr->getLifetimeEntry());
384389
if (!lifetimeDependenceInfo.has_value()) {
385390
return std::nullopt;
386391
}
392+
auto targetIndex = lifetimeDependenceInfo->getTargetIndex();
393+
if (lifetimeDependentTargets.contains(targetIndex)) {
394+
// TODO: Diagnose at the source location of the @lifetime attribute with
395+
// duplicate target.
396+
diags.diagnose(afd->getLoc(), diag::lifetime_dependence_duplicate_target);
397+
}
398+
lifetimeDependentTargets.insert(targetIndex);
387399
lifetimeDependencies.push_back(*lifetimeDependenceInfo);
388400
}
389401

test/Sema/lifetime_attr.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ func invalidDependence(_ x: consuming Klass) -> NE {
3333
NE()
3434
}
3535

36+
@lifetime(result: source)
37+
@lifetime(result: source) // TODO: display error here
38+
func invalidTarget(_ result: inout NE, _ source: consuming NE) { // expected-error{{invalid duplicate target lifetime dependencies on function}}
39+
result = source
40+
}

0 commit comments

Comments
 (0)