Skip to content

Commit 826e891

Browse files
committed
Diagnose multiple @Lifetime attributes with same target
1 parent 6f9cced commit 826e891

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
@@ -8005,6 +8005,8 @@ ERROR(lifetime_dependence_invalid_inherit_escapable_type, none,
80058005
ERROR(lifetime_dependence_cannot_use_parsed_borrow_consuming, none,
80068006
"invalid use of borrow dependence with consuming ownership",
80078007
())
8008+
ERROR(lifetime_dependence_duplicate_target, none,
8009+
"invalid duplicate target lifetime dependencies on function", ())
80088010

80098011
//===----------------------------------------------------------------------===//
80108012
// 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
@@ -34,3 +34,8 @@ func invalidDependence(_ x: consuming Klass) -> NE {
3434
NE()
3535
}
3636

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

0 commit comments

Comments
 (0)