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

Mention Result<!, E> in never docs. #49988

Merged
merged 2 commits into from
May 9, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/libstd/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ mod prim_bool { }
///
/// # `!` and generics
///
/// ## Infalliable errors

Choose a reason for hiding this comment

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

Typo: Infalliable -> Infallible

Copy link
Member

Choose a reason for hiding this comment

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

this still needs fixed

///
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
/// trait:
///
Expand Down Expand Up @@ -140,9 +142,59 @@ mod prim_bool { }
/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain
/// enum variants from generic types like `Result`.
///
/// ## Infinite loops
///
/// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to removed

Choose a reason for hiding this comment

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

Typo: removed -> remove

Copy link
Member

Choose a reason for hiding this comment

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

same

/// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not
/// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it
/// *has* errored.
///
/// For example, consider the case of a simple web server, which can be simplified to:
///
/// ```ignore (hypothetical-example)
Copy link
Member

Choose a reason for hiding this comment

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

I've never seen this notation, does this work?

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 actually copied it from an example earlier in the file, so, I assume so?

Copy link
Member

Choose a reason for hiding this comment

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

It doesn't do anything. It's recognized as non-rust code. That's pretty much all.

/// loop {
/// let (client, request) = get_request().expect("disconnected");
/// let response = request.process();
/// response.send(client);
/// }
/// ```
///
/// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection.
/// Instead, we'd like to keep track of this error, like this:
///
/// ```ignore (hypothetical-example)
/// loop {
/// match get_request() {
/// Err(err) => break err,
/// Ok((client, request)) => {
/// let response = request.process();
/// response.send(client);
/// },
/// }
/// }
/// ```
///
/// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it
/// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`]
/// instead:
///
/// ```ignore (hypothetical-example)
/// fn server_loop() -> Result<!, ConnectionError> {
Copy link
Member

Choose a reason for hiding this comment

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

I really like this example 👍 A thought: with #49162, it could even be

fn main() -> Result<!, ConnectionError>

Also, I think the Ok( isn't needed because loop returns !, which will coerce to the Result: https://play.rust-lang.org/?gist=1cc0b7e8032bec565768ab95f42c454d&version=nightly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My main reasoning for not making this main is that the idea is that you might in principle want a larger loop that handles the error. Also, while I agree that the loop can be coerced to Ok, I think that wrapping in an Ok is best to draw parallels to a non-infinite loop. If it seems more clear the other way though, I'll definitely change it.

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to leave off the Ok, but I can agree that this being not main makes a lot of sense

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'll leave off the Ok and explain the coercion.

/// Ok(loop {
/// let (client, request) = get_request()?;
/// let response = request.process();
/// response.send(client);
/// })
/// }
/// ```
///
/// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop
/// ever stops, it means that an error occurred.
///
/// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str
/// [`Result<String, !>`]: result/enum.Result.html
/// [`Result<T, !>`]: result/enum.Result.html
/// [`Result<!, E>`]: result/enum.Result.html
/// [`Ok`]: result/enum.Result.html#variant.Ok
/// [`String`]: string/struct.String.html
/// [`Err`]: result/enum.Result.html#variant.Err
Expand Down