Skip to content

Commit e5a3047

Browse files
committed
[SILGen] A noEagerMove consuming param is lexical.
1 parent 2a3c533 commit e5a3047

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
@@ -7050,8 +7050,11 @@ LifetimeAnnotation ParamDecl::getLifetimeAnnotation() const {
70507050
auto specifier = getSpecifier();
70517051
// Copyable parameters which are consumed have eager-move semantics.
70527052
if (specifier == ParamDecl::Specifier::Consuming &&
7053-
!getType()->isPureMoveOnly())
7053+
!getType()->isPureMoveOnly()) {
7054+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
7055+
return LifetimeAnnotation::Lexical;
70547056
return LifetimeAnnotation::EagerMove;
7057+
}
70557058
return getLifetimeAnnotationFromAttributes(this);
70567059
}
70577060

@@ -9244,8 +9247,11 @@ LifetimeAnnotation FuncDecl::getLifetimeAnnotation() const {
92449247
// Copyable parameters which are consumed have eager-move semantics.
92459248
if (getSelfAccessKind() == SelfAccessKind::Consuming) {
92469249
auto *selfDecl = getImplicitSelfDecl();
9247-
if (selfDecl && !selfDecl->getType()->isPureMoveOnly())
9250+
if (selfDecl && !selfDecl->getType()->isPureMoveOnly()) {
9251+
if (getAttrs().hasAttribute<NoEagerMoveAttr>())
9252+
return LifetimeAnnotation::Lexical;
92489253
return LifetimeAnnotation::EagerMove;
9254+
}
92499255
}
92509256
return getLifetimeAnnotationFromAttributes(this);
92519257
}

test/SILOptimizer/consuming_parameter.swift

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

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

0 commit comments

Comments
 (0)