@@ -105,6 +105,64 @@ pub const fn identity<T>(x: T) -> T {
105
105
x
106
106
}
107
107
108
+ /// Converts [`!`] (the never type) to any type.
109
+ ///
110
+ /// This is possible because `!` is uninhabited (has no values), so this function can't actually
111
+ /// be ever called at runtime.
112
+ ///
113
+ /// Even though `!` can be coerced to any type implicitly anyway (and indeed this function
114
+ /// implemented by just "returning" the argument), this is still useful, as this prevents the
115
+ /// fallback from happening during typechecking.
116
+ ///
117
+ /// For example, this snippet type checks:
118
+ ///
119
+ /// ```rust
120
+ /// let x: Result<_, ()> = Err(());
121
+ /// let y = match x {
122
+ /// Ok(v) => v,
123
+ /// Err(()) => return,
124
+ /// };
125
+ /// ```
126
+ ///
127
+ /// This is a bit unexpected, because the type of `y` is seemingly unbound (indeed, it can be any
128
+ /// type). However, the `match` unifies type of `v` with type of `return` (which is `!`), so `y`
129
+ /// becomes `!` (or `()`, because of backwards compatibility shenanigans).
130
+ ///
131
+ /// This can be avoided by adding `absurd`;
132
+ ///
133
+ /// ```compile_fail,E0282
134
+ /// use core::convert::absurd;
135
+ ///
136
+ /// let x: Result<_, ()> = Err(());
137
+ /// let y = match x { //~ error[E0282]: type annotations needed
138
+ /// Ok(v) => v,
139
+ ///
140
+ /// // the call to `absurd` *is* unreachable, but it's still important for type check reasons
141
+ /// #[allow(unreachable_code)]
142
+ /// Err(()) => absurd(return),
143
+ /// };
144
+ /// ```
145
+ ///
146
+ /// This might be handy when writing macros.
147
+ ///
148
+ /// `absurd` can also be passed to higher order functions, just like any other function:
149
+ ///
150
+ /// ```
151
+ /// #![feature(never_type, convert_absurd)]
152
+ /// use core::convert::absurd;
153
+ ///
154
+ /// let x: Result<_, !> = Ok(1);
155
+ /// let x: u32 = x.unwrap_or_else(absurd);
156
+ /// ```
157
+ ///
158
+ /// [`!`]: ../../std/primitive.never.html
159
+ #[ inline( always) ]
160
+ #[ unstable( feature = "convert_absurd" , issue = "124310" ) ]
161
+ #[ rustc_const_unstable( feature = "convert_absurd" , issue = "124310" ) ]
162
+ pub const fn absurd < T > ( x : !) -> T {
163
+ x
164
+ }
165
+
108
166
/// Used to do a cheap reference-to-reference conversion.
109
167
///
110
168
/// This trait is similar to [`AsMut`] which is used for converting between mutable references.
0 commit comments