@@ -105,6 +105,64 @@ pub const fn identity<T>(x: T) -> T {
105105 x
106106}
107107
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+ /// [`!`]: ../../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+
108166/// Used to do a cheap reference-to-reference conversion.
109167///
110168/// This trait is similar to [`AsMut`] which is used for converting between mutable references.
0 commit comments