]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/unwinding.md
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / doc / nomicon / unwinding.md
1 % Unwinding
2
3 Rust has a *tiered* error-handling scheme:
4
5 * If something might reasonably be absent, Option is used.
6 * If something goes wrong and can reasonably be handled, Result is used.
7 * If something goes wrong and cannot reasonably be handled, the thread panics.
8 * If something catastrophic happens, the program aborts.
9
10 Option and Result are overwhelmingly preferred in most situations, especially
11 since they can be promoted into a panic or abort at the API user's discretion.
12 Panics cause the thread to halt normal execution and unwind its stack, calling
13 destructors as if every function instantly returned.
14
15 As of 1.0, Rust is of two minds when it comes to panics. In the long-long-ago,
16 Rust was much more like Erlang. Like Erlang, Rust had lightweight tasks,
17 and tasks were intended to kill themselves with a panic when they reached an
18 untenable state. Unlike an exception in Java or C++, a panic could not be
19 caught at any time. Panics could only be caught by the owner of the task, at which
20 point they had to be handled or *that* task would itself panic.
21
22 Unwinding was important to this story because if a task's
23 destructors weren't called, it would cause memory and other system resources to
24 leak. Since tasks were expected to die during normal execution, this would make
25 Rust very poor for long-running systems!
26
27 As the Rust we know today came to be, this style of programming grew out of
28 fashion in the push for less-and-less abstraction. Light-weight tasks were
29 killed in the name of heavy-weight OS threads. Still, on stable Rust as of 1.0
30 panics can only be caught by the parent thread. This means catching a panic
31 requires spinning up an entire OS thread! This unfortunately stands in conflict
32 to Rust's philosophy of zero-cost abstractions.
33
34 There is an unstable API called `catch_panic` that enables catching a panic
35 without spawning a thread. Still, we would encourage you to only do this
36 sparingly. In particular, Rust's current unwinding implementation is heavily
37 optimized for the "doesn't unwind" case. If a program doesn't unwind, there
38 should be no runtime cost for the program being *ready* to unwind. As a
39 consequence, actually unwinding will be more expensive than in e.g. Java.
40 Don't build your programs to unwind under normal circumstances. Ideally, you
41 should only panic for programming errors or *extreme* problems.
42
43 Rust's unwinding strategy is not specified to be fundamentally compatible
44 with any other language's unwinding. As such, unwinding into Rust from another
45 language, or unwinding into another language from Rust is Undefined Behaviour.
46 You must *absolutely* catch any panics at the FFI boundary! What you do at that
47 point is up to you, but *something* must be done. If you fail to do this,
48 at best, your application will crash and burn. At worst, your application *won't*
49 crash and burn, and will proceed with completely clobbered state.