@@ -268,6 +268,53 @@ 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 `!` in a [coercion site], it implicitly inserts a
274
+ /// coercion to allow the type checker 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
+ /// This can lead to compilation errors if the type cannot be inferred:
290
+ ///
291
+ /// ```compile_fail
292
+ /// // this
293
+ /// { panic!() };
294
+ ///
295
+ /// // gets turned into this
296
+ /// { absurd(panic!()) }; // error: can't infer the type of `absurd`
297
+ /// ```
298
+ ///
299
+ /// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and
300
+ /// if it can't infer the type, it uses the fallback type instead:
301
+ /// ```rust, ignore
302
+ /// type Fallback = /* An arbitrarily selected type! */;
303
+ /// { absurd::<Fallback>(panic!()) }
304
+ /// ```
305
+ ///
306
+ /// This is what is known as "never type fallback".
307
+ ///
308
+ /// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously
309
+ /// coerced to `()`, even when it would not infer `()` without the fallback. There are plans to
310
+ /// change it in the [2024 edition] (and possibly in all editions on a later date); see
311
+ /// [Tracking Issue for making `!` fall back to `!`][fallback-ti].
312
+ ///
313
+ /// [coercion site]: <https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites>
314
+ /// [`()`]: prim@unit
315
+ /// [fallback-ti]: <https://github.com/rust-lang/rust/issues/123748>
316
+ /// [2024 edition]: <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html>
317
+ ///
271
318
#[ unstable( feature = "never_type" , issue = "35121" ) ]
272
319
mod prim_never { }
273
320
0 commit comments