Skip to content

Commit 7db2c6d

Browse files
committed
[sending] Make sending a no escape closure a default rather than consuming parameter
The reason why I am doing this is that: 1. We don't support no escaping closure parameters today and would like to leave the design space open. 2. These closures are bitwise copyable/trivial so marking them as specifically consuming doesn't really make sense.
1 parent 598e510 commit 7db2c6d

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,16 +2261,19 @@ ParamSpecifierRequest::evaluate(Evaluator &evaluator,
22612261
if (auto transferring = dyn_cast<TransferringTypeRepr>(nestedRepr)) {
22622262
// If we do not have an Ownership Repr, return implicit copyable consuming.
22632263
auto *base = transferring->getBase();
2264-
if (!isa<OwnershipTypeRepr>(base)) {
2264+
if (!param->getInterfaceType()->isNoEscape() &&
2265+
!isa<OwnershipTypeRepr>(base)) {
22652266
return ParamSpecifier::ImplicitlyCopyableConsuming;
22662267
}
22672268
nestedRepr = base;
22682269
}
22692270

22702271
if (auto sending = dyn_cast<SendingTypeRepr>(nestedRepr)) {
2271-
// If we do not have an Ownership Repr, return implicit copyable consuming.
2272+
// If we do not have an Ownership Repr and do not have a no escape type,
2273+
// return implicit copyable consuming.
22722274
auto *base = sending->getBase();
2273-
if (!isa<OwnershipTypeRepr>(base)) {
2275+
if (!param->getInterfaceType()->isNoEscape() &&
2276+
!isa<OwnershipTypeRepr>(base)) {
22742277
return ParamSpecifier::ImplicitlyCopyableConsuming;
22752278
}
22762279
nestedRepr = base;

test/Concurrency/sending_mangling.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,14 @@ extension SendingProtocol {
7979
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingResult() -> sending_mangling.NonSendableKlass : $@convention(method) <Self where Self : SendingProtocol> (@in_guaranteed Self) -> @sil_sending @owned NonSendableKlass {
8080
func sendingResult() -> sending NonSendableKlass { fatalError() }
8181

82-
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithFunctionSendingArg(__owned (sending __owned sending_mangling.NonSendableKlass) -> ()) -> () : $@convention(method) <Self where Self : SendingProtocol> (@sil_sending @owned @noescape @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> (), @in_guaranteed Self) -> () {
82+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithFunctionSendingArg((sending __owned sending_mangling.NonSendableKlass) -> ()) -> () : $@convention(method) <Self where Self : SendingProtocol> (@sil_sending @guaranteed @noescape @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> (), @in_guaranteed Self) -> () {
8383
func sendingArgWithFunctionSendingArg(_ x: sending (sending NonSendableKlass) -> ()) {}
8484

8585
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithFunctionSendingResult() -> (sending __owned sending_mangling.NonSendableKlass) -> () : $@convention(method) <Self where Self : SendingProtocol> (@in_guaranteed Self) -> @sil_sending @owned @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> () {
8686
func sendingArgWithFunctionSendingResult() -> sending (sending NonSendableKlass) -> () { fatalError() }
87+
88+
// CHECK: sil hidden [ossa] @(extension in sending_mangling):sending_mangling.SendingProtocol.sendingArgWithEscapingFunctionSendingArg(__owned (sending __owned sending_mangling.NonSendableKlass) -> ()) -> () : $@convention(method) <Self where Self : SendingProtocol> (@sil_sending @owned @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> (), @in_guaranteed Self) -> () {
89+
func sendingArgWithEscapingFunctionSendingArg(_ x: sending @escaping (sending NonSendableKlass) -> ()) {}
8790
}
8891

8992
// Make sure we only do not mangle in __shared if we are borrowed by default and

test/Concurrency/transfernonsendable_sending_params.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,10 @@ actor NonSendableInit {
411411
set { fatalError() }
412412
}
413413
}
414+
415+
func testNoCrashWhenSendingNoEscapeClosure() async {
416+
func test(_ x: sending () -> ()) async {}
417+
418+
let c = Klass()
419+
await test { print(c) }
420+
}

0 commit comments

Comments
 (0)