Skip to content

Commit

Permalink
Add info about ! and impl Trait
Browse files Browse the repository at this point in the history
  • Loading branch information
camelid committed Aug 30, 2020
1 parent 62850d8 commit 4aae781
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions library/std/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,47 @@ mod prim_bool {}
/// # `!` and traits
///
/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl`
/// which doesn't `panic!`. As it turns out, most traits can have an `impl` for `!`. Take [`Debug`]
/// which doesn't `panic!`. The reason is that functions returning an `impl Trait` cannot have
/// divergence, i.e., returning `!`, as their only possible code path. As an example, this code
/// doesn't compile:
///
/// ```compile_fail
/// use core::ops::Add;
///
/// fn foo() -> impl Add<u32> {
/// unimplemented!()
/// }
/// ```
///
/// While this code does:
///
/// ```
/// use core::ops::Add;
///
/// fn foo() -> impl Add<u32> {
/// if true {
/// unimplemented!()
/// } else {
/// 0
/// }
/// }
/// ```
///
/// The reason is that, in the first example, there are many possible types for `!` to coerce
/// to, because the function's return value is polymorphic. However, in the second example, the
/// other branch returns `0` which has a concrete type that `!` can be coerced to. See issue
/// [#36375] for more information on this quirk of `!`.
///
/// [#36375]: https://github.com/rust-lang/rust/issues/36375
///
/// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`]
/// for example:
///
/// ```
/// #![feature(never_type)]
/// # use std::fmt;
/// # trait Debug {
/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
/// # }
/// impl Debug for ! {
/// fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down

0 comments on commit 4aae781

Please sign in to comment.