@@ -268,6 +268,47 @@ mod prim_bool {}
268
268
/// [`Debug`]: fmt::Debug
269
269
/// [`default()`]: Default::default
270
270
///
271
+ /// # Never type fallback
272
+ ///
273
+ /// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible),
274
+ /// to allow type check to infer any type:
275
+ ///
276
+ /// ```rust,ignore (illustrative-and-has-placeholders)
277
+ /// // this
278
+ /// let x: u8 = panic!();
279
+ ///
280
+ /// // is (essentially) turned by the compiler into
281
+ /// let x: u8 = absurd(panic!());
282
+ ///
283
+ /// // where absurd is a function with the following signature
284
+ /// // (it's sound, because `!` always marks unreachable code):
285
+ /// fn absurd<T>(_: !) -> T { ... }
286
+ // FIXME: use `core::convert::absurd` here instead, once it's merged
287
+ /// ```
288
+ ///
289
+ /// While it's convenient to be able to use non-diverging code in one of the branches (like
290
+ /// `if a { b } else { return }`) this could lead to compilation errors:
291
+ ///
292
+ /// ```compile_fail
293
+ /// // this
294
+ /// { panic!() };
295
+ ///
296
+ /// // gets turned into this
297
+ /// { absurd(panic!()) }; // error: can't infer the type of `absurd`
298
+ /// ```
299
+ ///
300
+ /// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it can't
301
+ /// infer their type, it sets the type to the fallback type. `{ absurd::<Fallback>(panic!()) };`.
302
+ /// This is what is known as "never type fallback".
303
+ ///
304
+ /// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced
305
+ /// to `()`, even though `()` was never mentioned (because of the fallback). There are plans to
306
+ /// change it in 2024 edition (and possibly in all editions on a later date), see
307
+ /// [Tracking Issue for making `!` fall back to `!`][fallback-ti].
308
+ ///
309
+ /// [`()`]: prim@unit
310
+ /// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748
311
+ ///
271
312
#[ unstable( feature = "never_type" , issue = "35121" ) ]
272
313
mod prim_never { }
273
314
0 commit comments