From 23b67de1513f412d0df37ece3bd90a3fd653c444 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 26 Apr 2024 20:48:15 +0200 Subject: [PATCH 1/5] Document never type fallback in `!`'s docs --- library/core/src/primitive_docs.rs | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index bda1ee6f45712..99b132fe3996b 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -268,6 +268,47 @@ mod prim_bool {} /// [`Debug`]: fmt::Debug /// [`default()`]: Default::default /// +/// # Never type fallback +/// +/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible), +/// to allow type check to infer any type: +/// +/// ```rust,ignore (illustrative-and-has-placeholders) +/// // this +/// let x: u8 = panic!(); +/// +/// // is (essentially) turned by the compiler into +/// let x: u8 = absurd(panic!()); +/// +/// // where absurd is a function with the following signature +/// // (it's sound, because `!` always marks unreachable code): +/// fn absurd(_: !) -> T { ... } +// FIXME: use `core::convert::absurd` here instead, once it's merged +/// ``` +/// +/// While it's convenient to be able to use non-diverging code in one of the branches (like +/// `if a { b } else { return }`) this could lead to compilation errors: +/// +/// ```compile_fail +/// // this +/// { panic!() }; +/// +/// // gets turned into this +/// { absurd(panic!()) }; // error: can't infer the type of `absurd` +/// ``` +/// +/// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it can't +/// infer their type, it sets the type to the fallback type. `{ absurd::(panic!()) };`. +/// This is what is known as "never type fallback". +/// +/// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced +/// to `()`, even though `()` was never mentioned (because of the fallback). There are plans to +/// change it in 2024 edition (and possibly in all editions on a later date), see +/// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. +/// +/// [`()`]: prim@unit +/// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 +/// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} From b73bfd26e4ddd6e91debf86cbaeb060e7fbb4425 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Sat, 27 Apr 2024 00:47:23 +0200 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 99b132fe3996b..1839c56f16dd0 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible), -/// to allow type check to infer any type: +/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible) +/// to allow type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -297,8 +297,13 @@ mod prim_bool {} /// { absurd(panic!()) }; // error: can't infer the type of `absurd` /// ``` /// -/// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it can't -/// infer their type, it sets the type to the fallback type. `{ absurd::(panic!()) };`. +/// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and +/// if it can't infer their type, it sets the type to the fallback type: +/// ```rust, ignore +/// type Fallback = /* An arbitrarily selected type! */; +/// { absurd::(panic!()) } +/// ``` +/// /// This is what is known as "never type fallback". /// /// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced From 3a40e838bfc22c6415e32fcd94fd48e83e1844b1 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Thu, 2 May 2024 04:13:57 +0200 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Kevin Reid Co-authored-by: Herman Skogseth Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 1839c56f16dd0..d9c81239fc4b9 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` it implicitly inserts a coercion (if possible) -/// to allow type checker to infer any type: +/// When the compiler sees a value of type `!` in a [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites), it implicitly inserts a coercion +/// to allow the type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -286,8 +286,7 @@ mod prim_bool {} // FIXME: use `core::convert::absurd` here instead, once it's merged /// ``` /// -/// While it's convenient to be able to use non-diverging code in one of the branches (like -/// `if a { b } else { return }`) this could lead to compilation errors: +/// This can lead to compilation errors if the type cannot be inferred: /// /// ```compile_fail /// // this @@ -298,7 +297,7 @@ mod prim_bool {} /// ``` /// /// To prevent such errors, the compiler remembers where it inserted `absurd` calls, and -/// if it can't infer their type, it sets the type to the fallback type: +/// if it can't infer the type, it uses the fallback type instead: /// ```rust, ignore /// type Fallback = /* An arbitrarily selected type! */; /// { absurd::(panic!()) } @@ -306,9 +305,9 @@ mod prim_bool {} /// /// This is what is known as "never type fallback". /// -/// Historically fallback was [`()`], causing confusing behavior where `!` spontaneously coerced -/// to `()`, even though `()` was never mentioned (because of the fallback). There are plans to -/// change it in 2024 edition (and possibly in all editions on a later date), see +/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously coerced +/// to `()`, even when it would not infer `()` without the fallback. There are plans to +/// change it in the [2024 edition](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// /// [`()`]: prim@unit From e2eb053bba6fa585e64c6976660ed143ea8de930 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 04:19:43 +0200 Subject: [PATCH 4/5] Slightly reformat !'s docs after applying github suggestions --- library/core/src/primitive_docs.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index d9c81239fc4b9..2ca69d1faa2aa 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -270,8 +270,8 @@ mod prim_bool {} /// /// # Never type fallback /// -/// When the compiler sees a value of type `!` in a [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites), it implicitly inserts a coercion -/// to allow the type checker to infer any type: +/// When the compiler sees a value of type `!` in a [coercion site], it implicitly inserts a +/// coercion to allow the type checker to infer any type: /// /// ```rust,ignore (illustrative-and-has-placeholders) /// // this @@ -305,13 +305,15 @@ mod prim_bool {} /// /// This is what is known as "never type fallback". /// -/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously coerced -/// to `()`, even when it would not infer `()` without the fallback. There are plans to -/// change it in the [2024 edition](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) (and possibly in all editions on a later date); see +/// Historically, the fallback type was [`()`], causing confusing behavior where `!` spontaneously +/// coerced to `()`, even when it would not infer `()` without the fallback. There are plans to +/// change it in the [2024 edition] (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// +/// [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites) /// [`()`]: prim@unit /// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 +/// [2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html /// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} From e18b6e819e703a6f66c93e803655b62146f9d018 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Thu, 2 May 2024 06:04:16 +0200 Subject: [PATCH 5/5] fixup links in never type docs Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> --- library/core/src/primitive_docs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 2ca69d1faa2aa..18a9503cfd2f5 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -310,10 +310,10 @@ mod prim_bool {} /// change it in the [2024 edition] (and possibly in all editions on a later date); see /// [Tracking Issue for making `!` fall back to `!`][fallback-ti]. /// -/// [coercion site](https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites) +/// [coercion site]: /// [`()`]: prim@unit -/// [fallback-ti]: https://github.com/rust-lang/rust/issues/123748 -/// [2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html +/// [fallback-ti]: +/// [2024 edition]: /// #[unstable(feature = "never_type", issue = "35121")] mod prim_never {}