Function rustc_middle::ty::layout::fn_can_unwind
source · pub fn fn_can_unwind(
tcx: TyCtxt<'_>,
fn_def_id: Option<DefId>,
abi: Abi
) -> bool
Expand description
Calculates whether a function’s ABI can unwind or not.
This takes two primary parameters:
-
fn_def_id
- theDefId
of the function. If this is provided then we can determine more precisely if the function can unwind. If this is not provided then we will only infer whether the function can unwind or not based on the ABI of the function. For example, a function marked with#[rustc_nounwind]
is known to not unwind even if it’s using Rust ABI. -
abi
- this is the ABI that the function is defined with. This is the primary factor for determining whether a function can unwind or not.
Note that in this case unwinding is not necessarily panicking in Rust. Rust
panics are implemented with unwinds on most platform (when
-Cpanic=unwind
), but this also accounts for -Cpanic=abort
build modes.
Notably unwinding is disallowed for more non-Rust ABIs unless it’s
specifically in the name (e.g. "C-unwind"
). Unwinding within each ABI is
defined for each ABI individually, but it always corresponds to some form of
stack-based unwinding (the exact mechanism of which varies
platform-by-platform).
Rust functions are classified whether or not they can unwind based on the
active “panic strategy”. In other words Rust functions are considered to
unwind in -Cpanic=unwind
mode and cannot unwind in -Cpanic=abort
mode.
Note that Rust supports intermingling panic=abort and panic=unwind code, but
only if the final panic mode is panic=abort. In this scenario any code
previously compiled assuming that a function can unwind is still correct, it
just never happens to actually unwind at runtime.
This function’s answer to whether or not a function can unwind is quite impactful throughout the compiler. This affects things like:
- Calling a function which can’t unwind means codegen simply ignores any associated unwinding cleanup.
- Calling a function which can unwind from a function which can’t unwind
causes the
abort_unwinding_calls
MIR pass to insert a landing pad that aborts the process. - This affects whether functions have the LLVM
nounwind
attribute, which affects various optimizations and codegen.