Skip to content

Commit 9dbdfa8

Browse files
committed
[SILGen] Allow annotating self @_eagerMove.
Allow @_eagerMove (and @_lexical) to be applied to methods. Applying it there means that the self argument will have the attribute.
1 parent da2de4d commit 9dbdfa8

File tree

6 files changed

+68
-5
lines changed

6 files changed

+68
-5
lines changed

include/swift/AST/Attr.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ SIMPLE_DECL_ATTR(_eagerMove, EagerMove,
666666
UserInaccessible |
667667
ABIStableToAdd | ABIStableToRemove |
668668
APIStableToAdd | APIStableToRemove |
669-
OnParam | OnVar | OnNominalType,
669+
OnFunc | OnParam | OnVar | OnNominalType,
670670
117)
671671

672672
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,
@@ -679,7 +679,7 @@ SIMPLE_DECL_ATTR(_lexical, Lexical,
679679
UserInaccessible |
680680
ABIStableToAdd | ABIStableToRemove |
681681
APIStableToAdd | APIStableToRemove |
682-
OnParam | OnVar | OnNominalType,
682+
OnFunc | OnParam | OnVar | OnNominalType,
683683
119)
684684

685685
SIMPLE_DECL_ATTR(_assemblyVision, EmitAssemblyVisionRemarks,

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,6 +3209,8 @@ ERROR(reasync_without_async_parameter,none,
32093209
ERROR(inherits_executor_without_async,none,
32103210
"non-async functions cannot inherit an executor", ())
32113211

3212+
ERROR(lifetime_invalid_global_scope,none, "%0 is only valid on methods",
3213+
(DeclAttribute))
32123214
ERROR(eagermove_and_lexical_combined,none,
32133215
"@_eagerMove and @_lexical attributes are alternate styles of lifetimes "
32143216
"and can't be combined", ())

lib/SILGen/SILGenProlog.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,19 @@ struct ArgumentInitHelper {
355355
SILLocation loc(pd);
356356
loc.markAsPrologue();
357357

358-
ManagedValue argrv = makeArgument(ty, pd->isInOut(), pd->isNoImplicitCopy(),
359-
pd->getLifetimeAnnotation(), parent, loc);
358+
LifetimeAnnotation lifetimeAnnotation = LifetimeAnnotation::None;
359+
bool isNoImplicitCopy = false;
360+
if (pd->isSelfParameter()) {
361+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(pd->getDeclContext())) {
362+
lifetimeAnnotation = afd->getLifetimeAnnotation();
363+
}
364+
} else {
365+
lifetimeAnnotation = pd->getLifetimeAnnotation();
366+
isNoImplicitCopy = pd->isNoImplicitCopy();
367+
}
368+
369+
ManagedValue argrv = makeArgument(ty, pd->isInOut(), isNoImplicitCopy,
370+
lifetimeAnnotation, parent, loc);
360371

361372
if (pd->isInOut()) {
362373
assert(argrv.getType().isAddress() && "expected inout to be address");

lib/Sema/TypeCheckAttr.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
318318

319319
void visitUnsafeInheritExecutorAttr(UnsafeInheritExecutorAttr *attr);
320320

321+
bool visitLifetimeAttr(DeclAttribute *attr);
321322
void visitEagerMoveAttr(EagerMoveAttr *attr);
322323
void visitLexicalAttr(LexicalAttr *attr);
323324

@@ -6224,9 +6225,26 @@ void AttributeChecker::visitUnsafeInheritExecutorAttr(
62246225
}
62256226
}
62266227

6227-
void AttributeChecker::visitEagerMoveAttr(EagerMoveAttr *attr) {}
6228+
bool AttributeChecker::visitLifetimeAttr(DeclAttribute *attr) {
6229+
if (auto *funcDecl = dyn_cast<FuncDecl>(D)) {
6230+
auto declContext = funcDecl->getDeclContext();
6231+
// eagerMove attribute may only appear in type context
6232+
if (!declContext->getDeclaredInterfaceType()) {
6233+
diagnoseAndRemoveAttr(attr, diag::lifetime_invalid_global_scope, attr);
6234+
return true;
6235+
}
6236+
}
6237+
return false;
6238+
}
6239+
6240+
void AttributeChecker::visitEagerMoveAttr(EagerMoveAttr *attr) {
6241+
if (visitLifetimeAttr(attr))
6242+
return;
6243+
}
62286244

62296245
void AttributeChecker::visitLexicalAttr(LexicalAttr *attr) {
6246+
if (visitLifetimeAttr(attr))
6247+
return;
62306248
// @_lexical and @_eagerMove are opposites and can't be combined.
62316249
if (D->getAttrs().hasAttribute<EagerMoveAttr>()) {
62326250
diagnoseAndRemoveAttr(attr, diag::eagermove_and_lexical_combined);

test/SILGen/lexical_lifetime.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,24 @@ func lexical_borrow_arg_trivial(_ trivial: Trivial) {
129129
use_generic(trivial)
130130
}
131131

132+
extension C {
133+
// CHECK-LABEL: sil hidden [ossa] @lexical_method_attr : $@convention(method) (@owned C) -> () {
134+
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @_lexical @owned $C):
135+
// CHECK-LABEL: } // end sil function 'lexical_method_attr'
136+
@_silgen_name("lexical_method_attr")
137+
@_lexical
138+
__consuming
139+
func lexical_method_attr() {}
140+
141+
// CHECK-LABEL: sil hidden [ossa] @eagermove_method_attr : $@convention(method) (@owned C) -> () {
142+
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @_eagerMove @owned $C):
143+
// CHECK-LABEL: } // end sil function 'eagermove_method_attr'
144+
@_silgen_name("eagermove_method_attr")
145+
@_eagerMove
146+
__consuming
147+
func eagermove_method_attr() {}
148+
}
149+
132150
////////////////////////////////////////////////////////////////////////////////
133151
// Test }}
134152
////////////////////////////////////////////////////////////////////////////////

test/attr/lexical.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ func bar(@_lexical _ s: S) {} // okay
1515

1616
func baz(@_eagerMove _ c: C) {} // okay
1717

18+
@_eagerMove // expected-error {{@_eagerMove is only valid on methods}}
19+
func bazzoo(_ c: C) {}
20+
21+
@_lexical // expected-error {{@_lexical is only valid on methods}}
22+
func bazzoozoo(_ c: C) {}
23+
24+
extension C {
25+
@_eagerMove
26+
func pazzoo() {}
27+
28+
@_lexical
29+
func pazzoozoo() {}
30+
}
31+
1832
struct S2 {
1933
@_eagerMove let c: C // okay
2034
@_lexical let e: E // okay

0 commit comments

Comments
 (0)