|
67 | 67 | #[stable(feature = "rust1", since = "1.0.0")]
|
68 | 68 | mod prim_bool { }
|
69 | 69 |
|
| 70 | +#[doc(primitive = "never")] |
| 71 | +// |
| 72 | +/// The `!` type, also called "never". |
| 73 | +/// |
| 74 | +/// `!` represents the type of computations which never resolve to any value at all. For example, |
| 75 | +/// the [`exit`] function `fn exit(code: i32) -> !` exits the process without ever returning, and |
| 76 | +/// so returns `!`. |
| 77 | +/// |
| 78 | +/// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to |
| 79 | +/// write: |
| 80 | +/// |
| 81 | +/// ``` |
| 82 | +/// #![feature(never_type)] |
| 83 | +/// # fn foo() -> u32 { |
| 84 | +/// let x: ! = { |
| 85 | +/// return 123 |
| 86 | +/// }; |
| 87 | +/// # } |
| 88 | +/// ``` |
| 89 | +/// |
| 90 | +/// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never |
| 91 | +/// assigned a value (because `return` returns from the entire function), `x` can be given type |
| 92 | +/// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code |
| 93 | +/// would still be valid. |
| 94 | +/// |
| 95 | +/// A more realistic usage of `!` is in this code: |
| 96 | +/// |
| 97 | +/// ``` |
| 98 | +/// # fn get_a_number() -> Option<u32> { None } |
| 99 | +/// # loop { |
| 100 | +/// let num: u32 = match get_a_number() { |
| 101 | +/// Some(num) => num, |
| 102 | +/// None => break, |
| 103 | +/// }; |
| 104 | +/// # } |
| 105 | +/// ``` |
| 106 | +/// |
| 107 | +/// Both match arms must produce values of type [`u32`], but since `break` never produces a value |
| 108 | +/// at all we know it can never produce a value which isn't a [`u32`]. This illustrates another |
| 109 | +/// behaviour of the `!` type - expressions with type `!` will coerce into any other type. |
| 110 | +/// |
| 111 | +/// [`u32`]: primitive.str.html |
| 112 | +/// [`exit`]: process/fn.exit.html |
| 113 | +/// |
| 114 | +/// # `!` and generics |
| 115 | +/// |
| 116 | +/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] |
| 117 | +/// trait: |
| 118 | +/// |
| 119 | +/// ``` |
| 120 | +/// trait FromStr: Sized { |
| 121 | +/// type Err; |
| 122 | +/// fn from_str(s: &str) -> Result<Self, Self::Err>; |
| 123 | +/// } |
| 124 | +/// ``` |
| 125 | +/// |
| 126 | +/// When implementing this trait for [`String`] we need to pick a type for [`Err`]. And since |
| 127 | +/// converting a string into a string will never result in an error, the appropriate type is `!`. |
| 128 | +/// (Currently the type actually used is an enum with no variants, though this is only because `!` |
| 129 | +/// was added to Rust at a later date and it may change in the future). With an [`Err`] type of |
| 130 | +/// `!`, if we have to call [`String::from_str`] for some reason the result will be a |
| 131 | +/// [`Result<String, !>`] which we can unpack like this: |
| 132 | +/// |
| 133 | +/// ```ignore (string-from-str-error-type-is-not-never-yet) |
| 134 | +/// // NOTE: This does not work today! |
| 135 | +/// let Ok(s) = String::from_str("hello"); |
| 136 | +/// ``` |
| 137 | +/// |
| 138 | +/// Since the [`Err`] variant contains a `!`, it can never occur. So we can exhaustively match on |
| 139 | +/// [`Result<T, !>`] by just taking the [`Ok`] variant. This illustrates another behaviour of `!` - |
| 140 | +/// it can be used to "delete" certain enum variants from generic types like `Result`. |
| 141 | +/// |
| 142 | +/// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str |
| 143 | +/// [`Result<String, !>`]: result/enum.Result.html |
| 144 | +/// [`Result<T, !>`]: result/enum.Result.html |
| 145 | +/// [`Ok`]: result/enum.Result.html#variant.Ok |
| 146 | +/// [`String`]: string/struct.String.html |
| 147 | +/// [`Err`]: result/enum.Result.html#variant.Err |
| 148 | +/// [`FromStr`]: str/trait.FromStr.html |
| 149 | +/// |
| 150 | +/// # `!` and traits |
| 151 | +/// |
| 152 | +/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` |
| 153 | +/// which doesn't `panic!`. As is turns out, most traits can have an `impl` for `!`. Take [`Debug`] |
| 154 | +/// for example: |
| 155 | +/// |
| 156 | +/// ``` |
| 157 | +/// # #![feature(never_type)] |
| 158 | +/// # use std::fmt; |
| 159 | +/// # trait Debug { |
| 160 | +/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; |
| 161 | +/// # } |
| 162 | +/// impl Debug for ! { |
| 163 | +/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
| 164 | +/// *self |
| 165 | +/// } |
| 166 | +/// } |
| 167 | +/// ``` |
| 168 | +/// |
| 169 | +/// Once again we're using `!`'s ability to coerce into any other type, in this case |
| 170 | +/// [`fmt::Result`]. Since this method takes a `&!` as an argument we know that it can never be |
| 171 | +/// called (because there is no value of type `!` for it to be called with). Writing `*self` |
| 172 | +/// essentially tells the compiler "We know that this code can never be run, so just treat the |
| 173 | +/// entire function body has having type [`fmt::Result`]". This pattern can be used a lot when |
| 174 | +/// implementing traits for `!`. Generally, any trait which only has methods which take a `self` |
| 175 | +/// parameter should have such as impl. |
| 176 | +/// |
| 177 | +/// On the other hand, one trait which would not be appropriate to implement is [`Default`]: |
| 178 | +/// |
| 179 | +/// ``` |
| 180 | +/// trait Default { |
| 181 | +/// fn default() -> Self; |
| 182 | +/// } |
| 183 | +/// ``` |
| 184 | +/// |
| 185 | +/// Since `!` has no values, it has no default value either. It's true that we could write an |
| 186 | +/// `impl` for this which simply panics, but the same is true for any type (we could `impl |
| 187 | +/// Default` for (eg.) [`File`] by just making [`default()`] panic.) |
| 188 | +/// |
| 189 | +/// [`fmt::Result`]: fmt/type.Result.html |
| 190 | +/// [`File`]: fs/struct.File.html |
| 191 | +/// [`Debug`]: fmt/trait.Debug.html |
| 192 | +/// [`Default`]: default/trait.Default.html |
| 193 | +/// [`default()`]: default/trait.Default.html#tymethod.default |
| 194 | +/// |
| 195 | +#[unstable(feature = "never_type_impls", issue = "35121")] |
| 196 | +mod prim_never { } |
| 197 | + |
70 | 198 | #[doc(primitive = "char")]
|
71 | 199 | //
|
72 | 200 | /// A character type.
|
|
0 commit comments