Skip to content

Commit 53cb4a7

Browse files
committed
[SILGen] A noEagerMove consuming param is lexical.
1 parent 8e8e7fe commit 53cb4a7

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
@@ -7041,8 +7041,11 @@ LifetimeAnnotation ParamDecl::getLifetimeAnnotation() const {
70417041
auto specifier = getSpecifier();
70427042
// Copyable parameters which are consumed have eager-move semantics.
70437043
if (specifier == ParamDecl::Specifier::Consuming &&
7044-
!getType()->isPureMoveOnly())
7044+
!getType()->isPureMoveOnly()) {
7045+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
7046+
return LifetimeAnnotation::Lexical;
70457047
return LifetimeAnnotation::EagerMove;
7048+
}
70467049
return getLifetimeAnnotationFromAttributes();
70477050
}
70487051

@@ -9235,8 +9238,11 @@ LifetimeAnnotation FuncDecl::getLifetimeAnnotation() const {
92359238
// Copyable parameters which are consumed have eager-move semantics.
92369239
if (getSelfAccessKind() == SelfAccessKind::Consuming) {
92379240
auto *selfDecl = getImplicitSelfDecl();
9238-
if (selfDecl && !selfDecl->getType()->isPureMoveOnly())
9241+
if (selfDecl && !selfDecl->getType()->isPureMoveOnly()) {
9242+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
9243+
return LifetimeAnnotation::Lexical;
92399244
return LifetimeAnnotation::EagerMove;
9245+
}
92409246
}
92419247
return getLifetimeAnnotationFromAttributes();
92429248
}

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)