RFC 1513: less-unwinding

lang (panic | attributes | flags | cargo-profiles)

Summary

Stabilize implementing panics as aborts.

Motivation

Panics in Rust have long since been implemented with the intention of being caught at particular boundaries (for example the thread boundary). This is quite useful for isolating failures in Rust code, for example:

While these are examples where a recoverable panic is useful, there are many applications where recovering panics is undesirable or doesn't lead to anything productive:

Note: as an idea of the compile-time and object-size savings from disabling the extra codegen, compiling Cargo as a library is 11% faster (16s from 18s) and 13% smaller (15MB to 13MB). Sizable gains!

Overall, the ability to recover panics is something that needs to be decided at the application level rather than at the language level. Currently the compiler does not support the ability to translate panics to process aborts in a stable fashion, and the purpose of this RFC is to add such a venue.

With such an important codegen option, however, as whether or not exceptions can be caught, it's easy to get into a situation where libraries of mixed compilation modes are linked together, causing odd or unknown errors. This RFC proposes a situation similar to the design of custom allocators to alleviate this situation.

Detailed design

The major goal of this RFC is to develop a work flow around managing crates which wish to disable unwinding. This intends to set forth a complete vision for how these crates interact with the ecosystem at large. Much of this design will be similar to the custom allocator RFC.

High level design

This section serves as a high-level tour through the design proposed in this RFC. The linked sections provide more complete explanation as to what each step entails.

New Compiler Flags

The first component to this design is to have a stable flag to the compiler which configures how panic-related code is generated. This will be stabilized in the form:

$ rustc -C help

Available codegen options:

    ...
    -C             panic=val -- strategy to compile in for panic related code
    ...

There will currently be two supported strategies:

This codegen option will default to unwind if not specified (what happens today), and the value will be encoded into the crate metadata. This option is planned with extensibility in mind to future panic strategies if we ever implement some (return-based unwinding is at least one other possible option).

Panic Attributes

Very similarly to custom allocators, two new unstable crate attributes will be added to the compiler:

As with allocators, there are a number of limitations imposed by these attributes by the compiler:

The purpose of these limitations is to solve a number of problems that arise when switching panic strategies. For example with aborting panic crates won't have to link to runtime support of unwinding, or rustc will disallow mixing panic strategies by accident.

The actual API of panic runtimes will not be detailed in this RFC. These new attributes will be unstable, and consequently the API itself will also be unstable. It suffices to say, however, that like custom allocators a panic runtime will implement some public extern symbols known to the crates that need a panic runtime, and that's how they'll communicate/link up.

Panic Crates

Two new unstable crates will be added to the distribution for each target:

The compiler will assume that these crates are distributed for each platform where the standard library is also distributed (e.g. a crate that has #![needs_panic_runtime]).

Compiler defaults

The compiler will ship with a few defaults which affect how panic runtimes are selected in Rust programs. Specifically:

Cargo changes

In order to export this new feature to Cargo projects, a new option will be added to the [profile] section of manifests:

[profile.dev]
panic = 'unwind'

This will cause Cargo to pass -C panic=unwind to all rustc invocations for a crate graph. Cargo will have special knowledge, however, that for cargo test it cannot pass -C panic=abort.

Drawbacks

Alternatives

Unresolved questions