mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Closure literals are sometimes type-checked as one type then immediately converted to another type in the AST. One particular case of this is when a closure body never throws, but the closure is used as an argument to a function that takes a parameter that `throws`. Emitting this naively, by emitting the closure as its original type, then converting to throws, can be expensive for async closures, since that takes a reabstraction thunk. Even for non-async functions, we still want to get the benefit of reabstraction optimization for the closure literal through the conversion too. So if the function conversion just add `throws`, emit the closure as throwing, and pass down the context abstraction pattern when emitting the closure as well.
17 lines
764 B
Swift
17 lines
764 B
Swift
// RUN: %target-swift-frontend -emit-silgen %s -disable-availability-checking | %FileCheck %s
|
|
// REQUIRES: concurrency
|
|
|
|
@_silgen_name("takeThrowingAsyncClosure")
|
|
func takeThrowingAsyncClosure<T>(_: () async throws -> T)
|
|
|
|
// CHECK-LABEL: sil {{.*}} @{{.*}}34passNonthrowingAsyncClosureLiteral
|
|
func passNonthrowingAsyncClosureLiteral() {
|
|
// Check that the literal closure was emitted directly with an error return,
|
|
// without a reabstraction thunk to convert from nonthrowing.
|
|
// CHECK: [[INVOKE_FN:%.*]] = function_ref
|
|
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[INVOKE_FN]]
|
|
// CHECK: [[CALLEE:%.*]] = function_ref @takeThrowingAsyncClosure
|
|
// CHECK: apply [[CALLEE]]<Int>([[CLOSURE]])
|
|
takeThrowingAsyncClosure { return 42 }
|
|
}
|