1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/// Used as a return value to signify a fatal error occurred.
// `#![no_std]`: these arrive with the standard prelude and name no path, so a `std::`
// search cannot see them - and a `#[derive]` can use them without the name appearing
// in this file at all, which is why they are not trimmed by inspection.
use ToOwned;
use Box;
use format;
use ;
use vec;
use Vec;
;
pub use crateFatalErrorMarker;
// Upstream had `impl !Send for FatalError` so that `std::panic::panic_any(FatalError)` could
// not compile. Negative impls are unstable, and a marker field would break every
// `FatalError` unit expression. The guard has nothing left to guard here: there is no
// `panic_any` without `std`, and `raise` panics with a `&str` sentinel, never the value.
/// The message `FatalError::raise` panics with.
///
/// Not a marker type. `crate::unwind_janky::resume` cannot re-raise an arbitrary payload, so the
/// sentinel has to be something a `&str` payload can carry, and this is it.
const FATAL_SENTINEL: &str = "rustc fatal error (compilation refused)";
/// Run a closure, turning a fatal error inside it into an `Err` rather than a dead process.
///
/// The compiler aborts a compilation it refuses by unwinding a sentinel from deep in the
/// frontend, and this is the frame that receives it. Twelve places raise one, including every
/// `emit_fatal`, so without this a program the compiler declines - a syntax error, a missing
/// file - takes the whole process down. That is not hypothetical: it is what compiling a hello
/// world did before this was restored.
///
/// **A panic that is not a fatal error is re-raised, not swallowed.** An ICE must not be
/// silently converted into "the compiler refused your program"; the two are different answers
/// and only one of them is the user's fault. The sentinel is compared as a string because
/// `unwind_janky` hands back a `&str` payload rather than the `FatalErrorMarker` box that
/// `std::panic::resume_unwind` preserved.