|
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 | +/// let x: ! = { |
| 83 | +/// return 123; |
| 84 | +/// }; |
| 85 | +/// ``` |
| 86 | +/// |
| 87 | +/// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never |
| 88 | +/// assigned a value (because `return` returns from the entire function), `x` can be given type |
| 89 | +/// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code |
| 90 | +/// would still be valid. |
| 91 | +/// |
| 92 | +/// A more realistic usage of `!` is in this code: |
| 93 | +/// |
| 94 | +/// ``` |
| 95 | +/// let num: u32 = match get_a_number() { |
| 96 | +/// Some(num) => num, |
| 97 | +/// None => break, |
| 98 | +/// } |
| 99 | +/// ``` |
| 100 | +/// |
| 101 | +/// Both match arms must produce values of type `u32`, but since `break` never produces a value at |
| 102 | +/// all we know it can never produce a value which isn't a `u32`. This illustrates another |
| 103 | +/// behaviour of the `!` type - expressions with type `!` will coerce into any other type. |
| 104 | +/// |
| 105 | +/// [`exit`]: process/fn.exit.html |
| 106 | +/// |
| 107 | +/// # `!` and generics |
| 108 | +/// |
| 109 | +/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] |
| 110 | +/// trait: |
| 111 | +/// |
| 112 | +/// ``` |
| 113 | +/// trait FromStr { |
| 114 | +/// type Error; |
| 115 | +/// fn from_str(s: &str) -> Result<Self, Self::Error>; |
| 116 | +/// } |
| 117 | +/// ``` |
| 118 | +/// |
| 119 | +/// When implementing this trait for `String` we need to pick a type for `Error`. And since |
| 120 | +/// converting a string into a string will never result in an error, the appropriate type is `!`. |
| 121 | +/// If we have to call `String::from_str` for some reason, the result will be a |
| 122 | +/// `Result<String, !>`, which we can unpack like this: |
| 123 | +/// |
| 124 | +/// ``` |
| 125 | +/// let Ok(s) = String::from_str("hello"); |
| 126 | +/// ``` |
| 127 | +/// |
| 128 | +/// Since the `Err` variant contains a `!`, it can never occur. So we can exhaustively match on |
| 129 | +/// `Result<T, !>` by just taking the `Ok` variant. This illustrates another behaviour of `!` - it |
| 130 | +/// can be used to "delete" certain enum variants from generic types like `Result`. |
| 131 | +/// |
| 132 | +/// [`FromStr`]: str/trait.FromStr.html |
| 133 | +/// |
| 134 | +/// # `!` and traits |
| 135 | +/// |
| 136 | +/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` |
| 137 | +/// which doesn't `panic!`. As is turns out, most traits can have an `impl` for `!`. Take [`Debug`] |
| 138 | +/// for example: |
| 139 | +/// |
| 140 | +/// ``` |
| 141 | +/// impl Debug for ! { |
| 142 | +/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
| 143 | +/// *self |
| 144 | +/// } |
| 145 | +/// } |
| 146 | +/// ``` |
| 147 | +/// |
| 148 | +/// Once again we're using `!`'s ability to coerce into any other type, in this case `fmt::Result`. |
| 149 | +/// Since this method takes a `&!` as an argument we know that it can never be called (because |
| 150 | +/// there is no value of type `!` for it to be called with). Writing `*self` essentially tells the |
| 151 | +/// compiler "We know that this code can never be run, so just treat the entire function body has |
| 152 | +/// having type `fmt::Result`". This pattern can be used a lot when implementing traits for `!`. |
| 153 | +/// Generally, any trait which only has methods which take a `self` parameter should have such as |
| 154 | +/// impl. |
| 155 | +/// |
| 156 | +/// On the other hand, one trait which would not be appropriate to implement is [`Default`]: |
| 157 | +/// |
| 158 | +/// ``` |
| 159 | +/// trait Default { |
| 160 | +/// fn default() -> Self; |
| 161 | +/// } |
| 162 | +/// ``` |
| 163 | +/// |
| 164 | +/// Since `!` has no values, it has no default value either. It's true that we could write an |
| 165 | +/// `impl` for this which simply panics, but the same is true for any type (we could `impl |
| 166 | +/// Default` for (eg.) `File` by just making `default()` panic.) |
| 167 | +/// |
| 168 | +/// [`Debug`]: fmt/trait.Debug.html |
| 169 | +/// [`Default`]: default/trait.Default.html |
| 170 | +/// |
| 171 | +#[stable(feature = "rust1", since = "1.23.0")] |
| 172 | +mod prim_never { } |
| 173 | + |
70 | 174 | #[doc(primitive = "char")]
|
71 | 175 | //
|
72 | 176 | /// A character type.
|
|
0 commit comments