Skip to content

Commit 0ab5a87

Browse files
authored
Merge pull request #99 from sunhuachuang/upstream-master
Repeat value: question mark in main and tests (Add fix link commit)
2 parents 01b0001 + 510bb88 commit 0ab5a87

File tree

4 files changed

+7
-137
lines changed

4 files changed

+7
-137
lines changed

src/rust-2018/cargo-and-crates-io/cargo-workspaces-for-multi-package-projects.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ Cargo now has an additional level:
1111

1212
* A *workspace* contains one or more packages
1313

14-
This can be useful for larger projects. For example, [the `futures`
15-
respository] is a *workspace* that contains many related packages:
14+
This can be useful for larger projects. For example, [the `futures` package]
15+
is a *workspace* that contains many related packages:
1616

1717
* futures
1818
* futures-util
@@ -27,4 +27,4 @@ Workspaces allow these packages to be developed individually, but they share
2727
a single set of dependencies, and therefore have a single target directory
2828
and a single `Cargo.lock`.
2929

30-
For more details about workspaces, please see [the Cargo documentation](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-workspace-section).
30+
For more details about workspaces, please see [the Cargo documentation](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-workspace-section).
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Cargo and crates.io
22

3-
[check]: improved-error-messages.md
3+
[check]: cargo-check-for-faster-checking.md
44

55
In this chapter of the guide, we discuss a few improvements to `cargo` and crates.io.
6-
A notable addition here is the new [`cargo check`][check] command.
6+
A notable addition here is the new [`cargo check`][check] command.

src/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.md

-130
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
![Minimum Rust version: 1.22](https://img.shields.io/badge/Minimum%20Rust%20Version-1.22-brightgreen.svg) for `Option<T>`
66

7-
![Minimum Rust version: 1.26](https://img.shields.io/badge/Minimum%20Rust%20Version-1.26-brightgreen.svg) for using `?` in `main` and tests
8-
97
Rust has gained a new operator, `?`, that makes error handling more pleasant
108
by reducing the visual noise involved. It does this by solving one simple
119
problem. To illustrate, imagine we had some code to read some data from a
@@ -120,131 +118,3 @@ case, `?` will return a value for `Some(T)` and return `None` for `None`. One
120118
current restriction is that you cannot use `?` for both in the same function,
121119
as the return type needs to match the type you use `?` on. In the future,
122120
this restriction will be lifed.
123-
124-
## `?` in `main` and tests
125-
126-
Rust's error handling revolves around returning `Result<T, E>` and using `?`
127-
to propagate errors. For those who write many small programs and, hopefully,
128-
many tests, one common paper cut has been mixing entry points such as `main`
129-
and `#[test]`s with error handling.
130-
131-
As an example, you might have tried to write:
132-
133-
```rust,ignore
134-
use std::fs::File;
135-
136-
fn main() {
137-
let f = File::open("bar.txt")?;
138-
}
139-
```
140-
141-
Since `?` works by propagating the `Result` with an early return to the
142-
enclosing function, the snippet above does not work, and results today
143-
in the following error:
144-
145-
```rust,ignore
146-
error[E0277]: the `?` operator can only be used in a function that returns `Result`
147-
or `Option` (or another type that implements `std::ops::Try`)
148-
--> src/main.rs:5:13
149-
|
150-
5 | let f = File::open("bar.txt")?;
151-
| ^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
152-
|
153-
= help: the trait `std::ops::Try` is not implemented for `()`
154-
= note: required by `std::ops::Try::from_error`
155-
```
156-
157-
To solve this problem in Rust 2015, you might have written something like:
158-
159-
```rust
160-
// Rust 2015
161-
162-
# use std::process;
163-
# use std::error::Error;
164-
165-
fn run() -> Result<(), Box<Error>> {
166-
// real logic..
167-
Ok(())
168-
}
169-
170-
fn main() {
171-
if let Err(e) = run() {
172-
println!("Application error: {}", e);
173-
process::exit(1);
174-
}
175-
}
176-
```
177-
178-
However, in this case, the `run` function has all the interesting logic and
179-
`main` is just boilerplate. The problem is even worse for `#[test]`s, since
180-
there tend to be a lot more of them.
181-
182-
In Rust 2018 you can instead let your `#[test]`s and `main` functions return
183-
a `Result`:
184-
185-
```rust,no_run
186-
// Rust 2018
187-
188-
use std::fs::File;
189-
190-
fn main() -> Result<(), std::io::Error> {
191-
let f = File::open("bar.txt")?;
192-
193-
Ok(())
194-
}
195-
```
196-
197-
In this case, if say the file doesn't exist and there is an `Err(err)` somewhere,
198-
then `main` will exit with an error code (not `0`) and print out a `Debug`
199-
representation of `err`.
200-
201-
## More details
202-
203-
Getting `-> Result<..>` to work in the context of `main` and `#[test]`s is not
204-
magic. It is all backed up by a `Termination` trait which all valid return
205-
types of `main` and testing functions must implement. The trait is defined as:
206-
207-
```rust
208-
pub trait Termination {
209-
fn report(self) -> i32;
210-
}
211-
```
212-
213-
When setting up the entry point for your application, the compiler will use this
214-
trait and call `.report()` on the `Result` of the `main` function you have written.
215-
216-
Two simplified example implementations of this trait for `Result` and `()` are:
217-
218-
```rust
219-
# #![feature(process_exitcode_placeholder, termination_trait_lib)]
220-
# use std::process::ExitCode;
221-
# use std::fmt;
222-
#
223-
# pub trait Termination { fn report(self) -> i32; }
224-
225-
impl Termination for () {
226-
fn report(self) -> i32 {
227-
# use std::process::Termination;
228-
ExitCode::SUCCESS.report()
229-
}
230-
}
231-
232-
impl<E: fmt::Debug> Termination for Result<(), E> {
233-
fn report(self) -> i32 {
234-
match self {
235-
Ok(()) => ().report(),
236-
Err(err) => {
237-
eprintln!("Error: {:?}", err);
238-
# use std::process::Termination;
239-
ExitCode::FAILURE.report()
240-
}
241-
}
242-
}
243-
}
244-
```
245-
246-
As you can see in the case of `()`, a success code is simply returned.
247-
In the case of `Result`, the success case delegates to the implementation for
248-
`()` but prints out an error message and a failure exit code on `Err(..)`.
249-
250-
To learn more about the finer details, consult either [the tracking issue](https://github.com/rust-lang/rust/issues/43301) or [the RFC](https://github.com/rust-lang/rfcs/blob/master/text/1937-ques-in-main.md).
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Ownership and lifetimes
22

3-
[dmbm]: default-match-binding.md
3+
[dmbm]: default-match-bindings.md
44

55
In this chapter of the guide, we discuss a few improvements to ownership and lifetimes.
6-
One of the most notable of these is [default match binding modes][dmbm].
6+
One of the most notable of these is [default match binding modes][dmbm].

0 commit comments

Comments
 (0)