Skip to content

Commit 822d38f

Browse files
committed
[SILGen] A noEagerMove consuming param is lexical.
1 parent 2df8a76 commit 822d38f

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

lib/AST/Decl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7049,8 +7049,11 @@ LifetimeAnnotation ParamDecl::getLifetimeAnnotation() const {
70497049
auto specifier = getSpecifier();
70507050
// Copyable parameters which are consumed have eager-move semantics.
70517051
if (specifier == ParamDecl::Specifier::Consuming &&
7052-
!getType()->isPureMoveOnly())
7052+
!getType()->isPureMoveOnly()) {
7053+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
7054+
return LifetimeAnnotation::Lexical;
70537055
return LifetimeAnnotation::EagerMove;
7056+
}
70547057
return getLifetimeAnnotationFromAttributes();
70557058
}
70567059

@@ -9243,8 +9246,11 @@ LifetimeAnnotation FuncDecl::getLifetimeAnnotation() const {
92439246
// Copyable parameters which are consumed have eager-move semantics.
92449247
if (getSelfAccessKind() == SelfAccessKind::Consuming) {
92459248
auto *selfDecl = getImplicitSelfDecl();
9246-
if (selfDecl && !selfDecl->getType()->isPureMoveOnly())
9249+
if (selfDecl && !selfDecl->getType()->isPureMoveOnly()) {
9250+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
9251+
return LifetimeAnnotation::Lexical;
92479252
return LifetimeAnnotation::EagerMove;
9253+
}
92489254
}
92499255
return getLifetimeAnnotationFromAttributes();
92509256
}

test/SILOptimizer/consuming_parameter.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@ public func async_dead_arg_call(o: consuming AnyObject) async {
1616
await bar()
1717
}
1818

19+
// CHECK-LABEL: sil [ossa] @async_dead_arg_call_lexical : {{.*}} {
20+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @_lexical @owned
21+
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [[INSTANCE]]
22+
// CHECK: [[EXECUTOR:%[^,]+]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
23+
// CHECK: [[CALLEE:%[^,]+]] = function_ref @async_callee
24+
// CHECK: apply [[CALLEE]]()
25+
// CHECK: hop_to_executor [[EXECUTOR]]
26+
// CHECK: destroy_value [[MOVE]]
27+
// CHECK-LABEL: } // end sil function 'async_dead_arg_call_lexical'
28+
@_silgen_name("async_dead_arg_call_lexical")
29+
public func async_dead_arg_call_lexical(@_noEagerMove o: consuming AnyObject) async {
30+
await bar()
31+
// o should be destroyed here
32+
}
33+
34+
extension C {
35+
// CHECK-LABEL: sil [ossa] @async_dead_arg_call_lexical_method : {{.*}} {
36+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @_lexical @owned
37+
// CHECK-LABEL: } // end sil function 'async_dead_arg_call_lexical_method'
38+
@_silgen_name("async_dead_arg_call_lexical_method")
39+
@_noEagerMove
40+
consuming
41+
public func async_dead_arg_call_lexical_method() async {
42+
await bar()
43+
// self should be destroyed here
44+
}
45+
}
46+
1947
public class C {
2048
// CHECK-LABEL: sil [ossa] @async_dead_arg_call_method : {{.*}} {
2149
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @_eagerMove @owned

0 commit comments

Comments
 (0)