rustc_middle::ty::layout

Function fn_can_unwind

Source
pub fn fn_can_unwind(
    tcx: TyCtxt<'_>,
    fn_def_id: Option<DefId>,
    abi: ExternAbi,
) -> bool
Expand description

Calculates whether a function’s ABI can unwind or not.

This takes two primary parameters:

  • fn_def_id - the DefId 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.