Files
swift-mirror/test/SILGen/closure_literal_reabstraction_async.swift
Joe Groff 482cc8ae24 SILGen: Emit a closure literal in a function conversion as the converted type.
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.
2022-05-04 10:24:11 -07:00

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 }
}