bad/
never.rs

1/// A type alias to [`!` (never)][never] that works in places `!` doesn't
2/// currently in stable Rust.
3///
4/// # Examples
5///
6/// This is a way to indirectly refer to `!` in places where using it
7/// directly isn't allowed. Such as simply making an alias to `!` via normal
8/// means:
9///
10/// ```compile_fail
11/// type Never = !;
12/// ```
13///
14/// However, with this alias, you can make another alias to `!` indirectly:
15///
16/// ```
17/// type Never = bad::Never;
18/// ```
19///
20/// ## Return type
21///
22/// Just like `!` can already, `Never` can be used as a function return type:
23///
24/// ```
25/// fn error() -> bad::Never {
26///     panic!();
27/// }
28///
29/// let error_fn: fn() -> ! = error;
30/// ```
31///
32/// ## Input type
33///
34/// Currently, one can't use `!` as a function input type:
35///
36/// ```compile_fail
37/// fn forward(never: !) -> ! {
38///     never
39/// }
40/// ```
41///
42/// The same goes for expressing the function type:
43///
44/// ```compile_fail
45/// type F = fn(!) -> !;
46/// ```
47///
48/// By using `Never` in place of `!`, the function compiles:
49///
50/// ```
51/// fn forward(never: bad::Never) -> ! {
52///     never
53/// }
54///
55/// let forward_fn: fn(bad::Never) -> ! = forward;
56/// ```
57///
58/// ## Trait `impl`s on `!`
59///
60/// Currently, one can't `impl` custom traits directly on `!`:
61///
62/// ```compile_fail
63/// trait NeverType {}
64///
65/// impl NeverType for ! {}
66/// ```
67///
68/// By using `Never` in place of `!`, the `impl` works:
69///
70/// ```
71/// # trait NeverType {}
72/// impl NeverType for bad::Never {}
73/// ```
74///
75/// However, this isn't of much use since `!` turns into `()` in the context
76/// of trait bounds.
77///
78/// ## Array Item Type
79///
80/// Currently, one can't use `!` as the item type of an array:
81///
82/// ```compile_fail
83/// let array: [!; 0] = [];
84/// ```
85///
86/// The same for slices:
87///
88/// ```compile_fail
89/// let slice: &[!] = &[];
90/// ```
91///
92/// By using `Never` in place of `!` the above works:
93///
94/// ```
95/// let array: [bad::Never; 0] = [];
96/// let slice: &[bad::Never] = &[];
97/// ```
98///
99/// [never]: https://doc.rust-lang.org/std/primitive.never.html
100pub type Never = <F as HasOutput>::Output;
101
102// Declared public to prevent errors when externally used. This is locally
103// guarded against by denying `private_in_public` everywhere. However, it should
104// not be actually publicly exposed. This is locally guarded against by denying
105// `missing_docs` everywhere.
106pub trait HasOutput {
107    type Output;
108}
109
110impl<O> HasOutput for fn() -> O {
111    type Output = O;
112}
113
114type F = fn() -> !;