Skip to content
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

Merged
merged 6 commits into from
Dec 10, 2017
Merged

Add docs for never primitive #46232

merged 6 commits into from
Dec 10, 2017

Conversation

canndrew
Copy link
Contributor

/// [`Debug`]: fmt/trait.Debug.html
/// [`Default`]: default/trait.Default.html
///
#[stable(feature = "rust1", since = "1.23.0")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be attached to rust1, or would it be attached to never_type? I would assume the latter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's also the reason why tidy errors:

[00:03:19] tidy error: /checkout/src/libstd/primitive_docs.rs:171: mismatches to previous in: ["since"]
[00:03:19] tidy error: /checkout/src/libstd/primitive_docs.rs:247: mismatches to previous in: ["since"]

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to #[unstable(feature = "never_type_impls", issue = "35121")] since that's what's used in other places in libstd/libcore.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 24, 2017
@kennytm
Copy link
Member

kennytm commented Nov 24, 2017

The following doc tests failed:

[01:08:18] failures:
[01:08:18]     primitive_docs.rs - prim_never (line 114)
[01:08:18]     primitive_docs.rs - prim_never (line 127)
[01:08:18]     primitive_docs.rs - prim_never (line 144)
[01:08:18]     primitive_docs.rs - prim_never (line 81)
[01:08:18]     primitive_docs.rs - prim_never (line 95)
[01:08:18] failures:
[01:08:18] 
[01:08:18] ---- primitive_docs.rs - prim_never (line 114) stdout ----
[01:08:18] 	error[E0277]: the trait bound `Self: std::marker::Sized` is not satisfied
[01:08:18]  --> primitive_docs.rs:6:5
[01:08:18]   |
[01:08:18] 6 |     fn from_str(s: &str) -> Result<Self, Self::Error>;
[01:08:18]   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Self` does not have a constant size known at compile-time
[01:08:18]   |
[01:08:18]   = help: the trait `std::marker::Sized` is not implemented for `Self`
[01:08:18]   = help: consider adding a `where Self: std::marker::Sized` bound
[01:08:18]   = note: required by `std::result::Result`
[01:08:18] 
[01:08:18] thread 'rustc' panicked at 'couldn't compile the test', /checkout/src/librustdoc/test.rs:290:12
[01:08:18] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:08:18] 
[01:08:18] ---- primitive_docs.rs - prim_never (line 127) stdout ----
[01:08:18] 	error[E0599]: no function or associated item named `from_str` found for type `std::string::String` in the current scope
[01:08:18]  --> primitive_docs.rs:4:13
[01:08:18]   |
[01:08:18] 4 | let Ok(s) = String::from_str("hello");
[01:08:18]   |             ^^^^^^^^^^^^^^^^ function or associated item not found in `std::string::String`
[01:08:18]   |
[01:08:18]   = help: items from traits can only be used if the trait is in scope
[01:08:18] help: the following trait is implemented but not in scope, perhaps add a `use` for it:
[01:08:18]   |
[01:08:18] 3 | use std::str::FromStr;
[01:08:18]   |
[01:08:18] 
[01:08:18] thread 'rustc' panicked at 'couldn't compile the test', /checkout/src/librustdoc/test.rs:290:12
[01:08:18] 
[01:08:18] ---- primitive_docs.rs - prim_never (line 144) stdout ----
[01:08:18] 	error[E0433]: failed to resolve. Use of undeclared type or module `fmt`
[01:08:18]  --> primitive_docs.rs:5:35
[01:08:18]   |
[01:08:18] 5 |     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
[01:08:18]   |                                   ^^^ Use of undeclared type or module `fmt`
[01:08:18] 
[01:08:18] error[E0433]: failed to resolve. Use of undeclared type or module `fmt`
[01:08:18]  --> primitive_docs.rs:5:54
[01:08:18]   |
[01:08:18] 5 |     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
[01:08:18]   |                                                      ^^^ Use of undeclared type or module `fmt`
[01:08:18] 
[01:08:18] error[E0405]: cannot find trait `Debug` in this scope
[01:08:18]  --> primitive_docs.rs:4:6
[01:08:18]   |
[01:08:18] 4 | impl Debug for ! {
[01:08:18]   |      ^^^^^ not found in this scope
[01:08:18] help: possible candidate is found in another module, you can import it into scope
[01:08:18]   |
[01:08:18] 3 | use std::fmt::Debug;
[01:08:18]   |
[01:08:18] 
[01:08:18] error: The `!` type is experimental (see issue #35121)
[01:08:18]  --> primitive_docs.rs:4:16
[01:08:18]   |
[01:08:18] 4 | impl Debug for ! {
[01:08:18]   |                ^
[01:08:18]   |
[01:08:18]   = help: add #![feature(never_type)] to the crate attributes to enable
[01:08:18] 
[01:08:18] thread 'rustc' panicked at 'couldn't compile the test', /checkout/src/librustdoc/test.rs:290:12
[01:08:18] 
[01:08:18] ---- primitive_docs.rs - prim_never (line 81) stdout ----
[01:08:18] 	error: The `!` type is experimental (see issue #35121)
[01:08:18]  --> primitive_docs.rs:4:8
[01:08:18]   |
[01:08:18] 4 | let x: ! = {
[01:08:18]   |        ^
[01:08:18]   |
[01:08:18]   = help: add #![feature(never_type)] to the crate attributes to enable
[01:08:18] 
[01:08:18] thread 'rustc' panicked at 'couldn't compile the test', /checkout/src/librustdoc/test.rs:290:12
[01:08:18] 
[01:08:18] ---- primitive_docs.rs - prim_never (line 95) stdout ----
[01:08:18] 	error: expected one of `.`, `;`, `?`, or an operator, found `}`
[01:08:18]  --> primitive_docs.rs:8:1
[01:08:18]   |
[01:08:18] 7 | }
[01:08:18]   |  - expected one of `.`, `;`, `?`, or an operator here
[01:08:18] 8 | }
[01:08:18]   | ^ unexpected token
[01:08:18] 
[01:08:18] thread 'rustc' panicked at 'couldn't compile the test', /checkout/src/librustdoc/test.rs:290:12

@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 24, 2017
@canndrew
Copy link
Contributor Author

Is there a way to run doc tests separately?

Also, I just forced-pushed an amendment to that last commit but it didn't cancel the old travis job. So job #63107 can be cancelled (would be nice if it happened automatically though).

@kennytm
Copy link
Member

kennytm commented Nov 24, 2017

@canndrew Try

./x.py test --stage 1 src/libstd --test-args prim_never

If you mean without recompiling rustc... sorry not yet (#46180).

@QuietMisdreavus
Copy link
Member

Out of curiosity, is it possible to reuse the never_type gate, instead of the never_type_impls one, since this is really about the type itself? Or would that clash with the language feature of the same name and cause headaches in the unstable book?

@canndrew
Copy link
Contributor Author

Or would that clash with the language feature of the same name and cause headaches in the unstable book?

I don't know what headaches it would cause but I remember that there was a reason for having a separate never_type_impls gate.

@est31
Copy link
Member

est31 commented Nov 25, 2017

You can use one single feature gate for lib and language features. See #43089

@est31
Copy link
Member

est31 commented Nov 25, 2017

The unstable book handles them not really well. Documentation for the proc_macro feature appears both in the libary feature list and the language feature list.

Maybe it would be an idea to create a "common feature" list.

@canndrew
Copy link
Contributor Author

@est31 Cool. I've made a separate PR to rename never_type_impls to never_type: #46250

@QuietMisdreavus
Copy link
Member

Looks good, but i have one request: Can you change this line here to primitive_type(f, PrimitiveType::Never, "!") so automatically-printed ! types start linking to this page?

@QuietMisdreavus
Copy link
Member

@rust-lang/docs Any comments on the doc text here? I think it's good, but it would be nice to have more eyes on it.

@@ -67,6 +67,123 @@
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_bool { }

#[doc(primitive = "never")]
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this line?

Copy link
Member

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.

Copy link
Member

@GuillaumeGomez GuillaumeGomez Nov 28, 2017

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

@@ -67,6 +67,123 @@
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_bool { }

#[doc(primitive = "never")]
//
/// The `!` type, also called "never".
Copy link
Member

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The 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, *const T, and *mut T", "References, both shared and mutable", "A finite heterogeneous sequence, (T, U, ..)", all of which appear in the current docs. Do you have a better suggestion?

/// so returns `!`.
///
/// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to
/// write
Copy link
Member

@GuillaumeGomez GuillaumeGomez Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add :.

/// }
/// ```
///
/// When implementing this trait for `String` we need to pick a type for `Err`. And since
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add urls for String and Err.

/// let Ok(s) = String::from_str("hello");
/// ```
///
/// Since the `Err` variant contains a `!`, it can never occur. So we can exhaustively match on
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for Err.

/// ```
///
/// Since the `Err` variant contains a `!`, it can never occur. So we can exhaustively match on
/// `Result<T, !>` by just taking the `Ok` variant. This illustrates another behaviour of `!` - it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URLs for Result and Ok.

/// # }
/// ```
///
/// Both match arms must produce values of type `u32`, but since `break` never produces a value at
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for u32.

/// ```
///
/// Both match arms must produce values of type `u32`, but since `break` never produces a value at
/// all we know it can never produce a value which isn't a `u32`. This illustrates another
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for u32.

/// 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, the appropriate type is `!`.
/// (Currently the type actually used is an enum with no variants, though this is only because `!`
/// was added to Rust at a later date and it may change in the future). With an `Err` type of `!`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for Err.

/// converting a string into a string will never result in an error, the appropriate type is `!`.
/// (Currently the type actually used is an enum with no variants, though this is only because `!`
/// was added to Rust at a later date and it may change in the future). With an `Err` type of `!`,
/// if we have to call `String::from_str` for some reason the result will be a `Result<String, !>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URLs for String::from_str, Result and String.

/// }
/// ```
///
/// Once again we're using `!`'s ability to coerce into any other type, in this case `fmt::Result`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for fmt::Result.

/// 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 `!`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL for fmt::Result.

///
/// 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.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URLs for File and default().

@GuillaumeGomez
Copy link
Member

Text seems good to me (at one exception). However a lot of small nits. :)

@canndrew
Copy link
Contributor Author

Thanks for the feedback. I've added all those missing links.

Copy link
Member

@QuietMisdreavus QuietMisdreavus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for letting this get stale! I looked over the docs again and i have a couple nits. Once these are settled we can go ahead and merge it!

/// let x: ! = {
/// return 123
/// };
/// # }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should show the feature flag here, since it's needed to give x the proper type.

/// [`Result<String, !>`] which we can unpack like this:
///
/// ```ignore (string-from-str-error-type-is-not-never-yet)
/// let Ok(s) = String::from_str("hello");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know these ignore blocks get a little info tooltip and callout border now, but i'd prefer it if we had a comment in here along the lines of "NOTE: This does not work today!", just to sate my paranoia about people blindly copy/pasting examples from docs.

@shepmaster shepmaster added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 9, 2017
@shepmaster
Copy link
Member

Heads up from triage @canndrew — you've got some pending feedback to address!

@canndrew
Copy link
Contributor Author

Thanks for the reminder! I've pushed a couple of small fixes.

@QuietMisdreavus
Copy link
Member

Thanks so much!

@bors r+

@bors
Copy link
Contributor

bors commented Dec 10, 2017

📌 Commit 172f16b has been approved by QuietMisdreavus

@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 10, 2017
@bors
Copy link
Contributor

bors commented Dec 10, 2017

⌛ Testing commit 172f16b with merge 2d4df95...

bors added a commit that referenced this pull request Dec 10, 2017
@bors
Copy link
Contributor

bors commented Dec 10, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: QuietMisdreavus
Pushing 2d4df95 to master...

@bors bors merged commit 172f16b into rust-lang:master Dec 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants