-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add docs for never primitive #46232
Add docs for never primitive #46232
Changes from 1 commit
6612590
3184520
bd7d541
afd094a
a2e79a7
172f16b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,110 @@ | |
#[stable(feature = "rust1", since = "1.0.0")] | ||
mod prim_bool { } | ||
|
||
#[doc(primitive = "never")] | ||
// | ||
/// The `!` type, also called "never". | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This "introduction" sounds strange. I expected to have something after directly but just a dot. So strange. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This kind of introduction line matches the other primitives. Compare with "Raw, unsafe pointers, |
||
/// | ||
/// `!` represents the type of computations which never resolve to any value at all. For example, | ||
/// the [`exit`] function `fn exit(code: i32) -> !` exits the process without ever returning, and | ||
/// so returns `!`. | ||
/// | ||
/// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to | ||
/// write | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add |
||
/// | ||
/// ``` | ||
/// let x: ! = { | ||
/// return 123; | ||
/// }; | ||
/// ``` | ||
/// | ||
/// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never | ||
/// assigned a value (because `return` returns from the entire function), `x` can be given type | ||
/// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code | ||
/// would still be valid. | ||
/// | ||
/// A more realistic usage of `!` is in this code: | ||
/// | ||
/// ``` | ||
/// let num: u32 = match get_a_number() { | ||
/// Some(num) => num, | ||
/// None => break, | ||
/// } | ||
/// ``` | ||
/// | ||
/// Both match arms must produce values of type `u32`, but since `break` never produces a value at | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URL for |
||
/// all we know it can never produce a value which isn't a `u32`. This illustrates another | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URL for |
||
/// behaviour of the `!` type - expressions with type `!` will coerce into any other type. | ||
/// | ||
/// [`exit`]: process/fn.exit.html | ||
/// | ||
/// # `!` and generics | ||
/// | ||
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] | ||
/// trait: | ||
/// | ||
/// ``` | ||
/// trait FromStr { | ||
/// type Error; | ||
/// fn from_str(s: &str) -> Result<Self, Self::Error>; | ||
/// } | ||
/// ``` | ||
/// | ||
/// When implementing this trait for `String` we need to pick a type for `Error`. And since | ||
/// converting a string into a string will never result in an error, the appropriate type is `!`. | ||
/// If we have to call `String::from_str` for some reason, the result will be a | ||
/// `Result<String, !>`, which we can unpack like this: | ||
/// | ||
/// ``` | ||
/// let Ok(s) = String::from_str("hello"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know these |
||
/// ``` | ||
/// | ||
/// Since the `Err` variant contains a `!`, it can never occur. So we can exhaustively match on | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URL for |
||
/// `Result<T, !>` by just taking the `Ok` variant. This illustrates another behaviour of `!` - it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URLs for |
||
/// can be used to "delete" certain enum variants from generic types like `Result`. | ||
/// | ||
/// [`FromStr`]: str/trait.FromStr.html | ||
/// | ||
/// # `!` and traits | ||
/// | ||
/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` | ||
/// which doesn't `panic!`. As is turns out, most traits can have an `impl` for `!`. Take [`Debug`] | ||
/// for example: | ||
/// | ||
/// ``` | ||
/// impl Debug for ! { | ||
/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
/// *self | ||
/// } | ||
/// } | ||
/// ``` | ||
/// | ||
/// Once again we're using `!`'s ability to coerce into any other type, in this case `fmt::Result`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URL for |
||
/// Since this method takes a `&!` as an argument we know that it can never be called (because | ||
/// there is no value of type `!` for it to be called with). Writing `*self` essentially tells the | ||
/// compiler "We know that this code can never be run, so just treat the entire function body has | ||
/// having type `fmt::Result`". This pattern can be used a lot when implementing traits for `!`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URL for |
||
/// Generally, any trait which only has methods which take a `self` parameter should have such as | ||
/// impl. | ||
/// | ||
/// On the other hand, one trait which would not be appropriate to implement is [`Default`]: | ||
/// | ||
/// ``` | ||
/// trait Default { | ||
/// fn default() -> Self; | ||
/// } | ||
/// ``` | ||
/// | ||
/// Since `!` has no values, it has no default value either. It's true that we could write an | ||
/// `impl` for this which simply panics, but the same is true for any type (we could `impl | ||
/// Default` for (eg.) `File` by just making `default()` panic.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URLs for |
||
/// | ||
/// [`Debug`]: fmt/trait.Debug.html | ||
/// [`Default`]: default/trait.Default.html | ||
/// | ||
#[stable(feature = "rust1", since = "1.23.0")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be attached to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's also the reason why tidy errors:
because rust1 has been defined elsewhere already (probably with a since field of "1.0.0") and the since field that @canndrew specified "1.23.0" mismatches. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed it to |
||
mod prim_never { } | ||
|
||
#[doc(primitive = "char")] | ||
// | ||
/// A character type. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why it was there in the first place, but it does match the other primitive docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should remove them then!
@rust-lang/cleanup-team