Skip to main content

never

Primitive Type never 

1.100.0
Expand description

The ! type, also called “never”.

! is the canonical uninhabited type. ! represents the type of diverging computations – computations which never resolve to any value.

Another way to look at it is that since ! has no values (since it is uninhabited), it is a marker for unreachable code.

For example, the exit function is defined as returning !, to signify that it doesn’t return normally (as it exits the process instead). Thus, any code following a call to exit is unreachable. (panic! works the same way.)

Similarly, return, break, continue, become, and infinite loop expressions all have type !, as the code following them is unreachable.

fn meow() -> u32 {
    let _: ! = return 123;
    // code following the `return` is unreachable...
    // since it returns from the function
}

The let binding above is pointless, but shows that return expressions have type !.

§Never-to-any coercion

The never type can be coerced to any type:

fn nyaa<T>(x: !) -> T {
    x // there is an implicit ! -> T coercion here
}

This is sound because a value of type ! can never exist, and any coercion of such a value will never actually execute.

This is useful when an if branch or match arm returns early (or panics, or falls into an infinite loop, etc.).

fn mrrrow(option: Option<u32>) {
    let value = match option {
        // `x` has type `u32`
        Some(x) => x,
        // `return` has type `!`, which is then coerced to `u32`,
        // allowing the `match` to pass type checking.
        None => return,
    };
    // ...
}

fn miau(fallible: impl Fn() -> Result<i64, u32>) -> i64 {
    loop {
        let err = match fallible() {
             Ok(res) => break res,
             Err(err) => err,
        };
        // retry logic...
    }
}

§Infallible errors & disabling enum variants

The never type can also be used to mark operations as infallible.

Consider the FromStr trait:

trait FromStr: Sized {
    type Err;
    fn from_str(s: &str) -> Result<Self, Self::Err>;
}

When implementing this trait for String, we need to pick a type for Err. And since converting a string into a string will never result in an error, we would like to guarantee to the caller that we never return Err(_).

One way to do this is to set the error type to !. Since the never type has no values, the Err variant of a Result<T, !> cannot be constructed either. Moreover, the compiler can recognise this fact, and doesn’t require you to handle the Err case:

// we can exhaustively pattern match with just `Ok`
let Ok(s) = String::from_str("hello");

The same works for any enum, not just Result, and also for any uninhabited type, not just !:

// An enum with no variants is an example of an uninhabited type
enum Void {}

enum Onomatopoeias {
    // This variant can't be created and thus doesn't have to be matched
    Miu(!),
    // It doesn't matter if there are other fields,
    // as long as at least one of them is uninhabited
    Nya(u32, !),
    // Other uninhabited types have the same effect as the never type
    Mjau(Void),

    // Variants without uninhabited fields have to be handled as usual of course
    Miaow,
    // Even though `!` is uninhabited, `Option<!>` is inhabited by the `None` variant
    Myaaoo(Option<!>)
}

use Onomatopoeias::*;

_ = |x: Onomatopoeias| match x {
    Miaow => 0,
    Myaaoo(None) => 1,
};

§Implementing traits for !

At first glance there is no reason to implement any traits for !. Many trait methods take self as an argument, so calling them on ! is impossible.

However, when ! is used as a generic argument, it must still satisfy any trait bounds imposed on it. For example, Result<T, E> implements Clone if both T and E also implement it. In order for Result<T, !> to implement Clone, ! must do so as well.

In general, if a trait only has methods taking a self parameter (or &self, or an argument of type Self, etc.), consider implementing it for !. In such cases the implementation is trivial, thanks to never-to-any coercion. As an example, take the Debug trait:

impl Debug for ! {
    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
        // we can dereference `self` (which has type `&!`) to get `!`,
        // which then coerces to `fmt::Result`
        *self
    }
}

On the other hand, one trait which would not be appropriate to implement for ! is Default:

trait Default {
    fn default() -> Self;
}

Since ! has no values, it has no default value either. There is no meaningful implementation for default, since it would have to return ! – in other words it would need to diverge. While one could write an implementation using panic! or an infinite loop, or something alike, that would not be useful.

§! as impl Trait

When prototyping functions, one can use todo! (which has type !) to make the incomplete code type-check:

fn mrnjau() -> u32 {
    todo!() // `!` coerces to `u32`
}

However, even though ! can coerce to any type, this does not always work with functions returning impl Trait:

fn mjav() -> impl Iterator<Item = f32> {
    todo!()
}
error[E0277]: `!` is not an iterator
 --> src/lib.rs:1:14
  |
1 | fn mjav() -> impl Iterator<Item = f32> {
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^ `!` is not an iterator
2 |     todo!()
  |     ------- return type was inferred to be `!` here
  |
  = help: the trait `Iterator` is not implemented for `!`

This is because impl Trait is not a concrete type, but rather a way to tell the compiler that a function’s return type is hidden, and the only thing which can be assumed about the hidden type is that it implements Trait.

In this case, the hidden return type is inferred to be !, which does not implement Iterator. One fix for this is to explicitly cast ! to a type which implements the trait:

fn mjav() -> impl Iterator<Item = f32> {
    todo!() as std::iter::Empty<_>
}

Implementations§

Trait Implementations§

1.100.0 (const: unstable) · Source§

impl Clone for !

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)
where Self:,

Performs copy-assignment from source. Read more
1.100.0 · Source§

impl Copy for !

1.100.0 · Source§

impl Debug for !

Source§

fn fmt(&self, _: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
1.100.0 · Source§

impl Display for !

Source§

fn fmt(&self, _: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
1.100.0 (const: unstable) · Source§

impl Eq for !

1.0.0 (const: unstable) · Source§

#[doc(hidden)]
fn assert_receiver_is_total_eq(&self)

👎Deprecated since 1.95.0:

implementation detail of #[derive(Eq)]

Source§

#[doc(hidden)]
fn assert_fields_are_eq(&self)

🔬This is a nightly-only experimental API. (derive_eq_internals)
1.100.0 · Source§

impl Error for !

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
Source§

#[doc(hidden)]
fn type_id(&self, _: Internal) -> TypeId
where Self: 'static,

🔬This is a nightly-only experimental API. (error_type_id #60784)
Gets the TypeId of self.
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access #99301)
Provides type-based access to context intended for error reports. Read more
1.100.0 (const: unstable) · Source§

impl From<!> for TryFromIntError

Source§

fn from(never: !) -> TryFromIntError

Converts to this type from the input type.
1.36.0 (const: unstable) · Source§

impl From<!> for TryFromSliceError

Source§

fn from(x: Infallible) -> TryFromSliceError

Converts to this type from the input type.
1.29.0 · Source§

impl Hash for !

Source§

fn hash<H: Hasher>(&self, _: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
where Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
1.60.0 (const: unstable) · Source§

impl Not for !

Source§

type Output = !

The resulting type after applying the ! operator.
Source§

fn not(self) -> !

Performs the unary ! operation. Read more
1.100.0 (const: unstable) · Source§

impl Ord for !

Source§

fn cmp(&self, _: &!) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to #147781)
Restrict a value to a certain range. Read more
1.100.0 (const: unstable) · Source§

impl PartialEq for !

Source§

fn eq(&self, _: &!) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
1.100.0 (const: unstable) · Source§

impl PartialOrd for !

Source§

fn partial_cmp(&self, _: &!) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

#[doc(hidden)]
fn __chaining_lt(&self, other: &Rhs) -> ControlFlow<bool>

🔬This is a nightly-only experimental API. (partial_ord_chaining_methods)
If self == other, returns ControlFlow::Continue(()). Otherwise, returns ControlFlow::Break(self < other). Read more
Source§

#[doc(hidden)]
fn __chaining_le(&self, other: &Rhs) -> ControlFlow<bool>

🔬This is a nightly-only experimental API. (partial_ord_chaining_methods)
Same as __chaining_lt, but for <= instead of <.
Source§

#[doc(hidden)]
fn __chaining_gt(&self, other: &Rhs) -> ControlFlow<bool>

🔬This is a nightly-only experimental API. (partial_ord_chaining_methods)
Same as __chaining_lt, but for > instead of <.
Source§

#[doc(hidden)]
fn __chaining_ge(&self, other: &Rhs) -> ControlFlow<bool>

🔬This is a nightly-only experimental API. (partial_ord_chaining_methods)
Same as __chaining_lt, but for >= instead of <.
Source§

impl TrivialClone for !

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit #126799)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Printable for T
where T: Copy + Debug,

Source§

impl<T> SizeHint for T
where T: ?Sized,

Source§

default fn lower_bound(&self) -> usize

🔬This is a nightly-only experimental API. (core_io_internals)
Returns a lower bound on the number of elements this container-like item contains. For example, an array [u8; 12] could return any value between 0 and 12 inclusively as a correct implementation. Read more
Source§

default fn upper_bound(&self) -> Option<usize>

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an upper bound on the number of elements this container-like item contains if it can be determined, otherwise None. Read more
Source§

final fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an estimate for the number of elements this container like type contains. Read more
Source§

impl<T> SizedTypeProperties for T

Source§

#[doc(hidden)]
const SIZE: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGNMENT: Alignment = _

🔬This is a nightly-only experimental API. (ptr_alignment_type #102070)
Source§

#[doc(hidden)]
const IS_ZST: bool = _

🔬This is a nightly-only experimental API. (sized_type_properties)
true if this type requires no storage. false if its size is greater than zero. Read more
Source§

#[doc(hidden)]
const LAYOUT: Layout = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const MAX_SLICE_LEN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
The largest safe length for a [Self]. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.