Skip to content

Commit 093b3a7

Browse files
committed
Document never type fallback in !'s docs
1 parent ad89cf0 commit 093b3a7

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

core/src/primitive_docs.rs

+41
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,47 @@ mod prim_bool {}
268268
/// [`Debug`]: fmt::Debug
269269
/// [`default()`]: Default::default
270270
///
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+
///
271312
#[unstable(feature = "never_type", issue = "35121")]
272313
mod prim_never {}
273314

0 commit comments

Comments
 (0)