Skip to content

Commit c4530f2

Browse files
author
Jakub Bukaj
committed
---
yaml --- r: 160223 b: refs/heads/snap-stage3 c: 8997b09 h: refs/heads/master i: 160221: 5614b3c 160219: aeef252 160215: 36d0cfc 160207: 4a0f782 160191: 05fc61b v: v3
1 parent a37d5eb commit c4530f2

File tree

295 files changed

+10986
-8422
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

295 files changed

+10986
-8422
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: bfaa7bcab3459907014c31d3bf980f65ccd14b08
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 2aa241d76f5168dc554583d2347e6c74e9a7d3bc
4+
refs/heads/snap-stage3: 8997b098d3d5f5c5170cd5b4b5356ae6d6ce7f4a
55
refs/heads/try: 225de0d60f8ca8dcc62ab2fd8818ebbda4b58cfe
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d

branches/snap-stage3/configure

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ do
10311031
make_dir $h/test/doc-guide-tasks
10321032
make_dir $h/test/doc-guide-plugin
10331033
make_dir $h/test/doc-guide-crates
1034+
make_dir $h/test/doc-guide-error-handling
10341035
make_dir $h/test/doc-rust
10351036
done
10361037

branches/snap-stage3/mk/crates.mk

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ TARGET_CRATES := libc std green native flate arena term \
5353
serialize sync getopts collections test time rand \
5454
log regex graphviz core rbml alloc rustrt \
5555
unicode
56-
HOST_CRATES := syntax rustc rustdoc regex_macros fmt_macros \
56+
HOST_CRATES := syntax rustc rustc_trans rustdoc regex_macros fmt_macros \
5757
rustc_llvm rustc_back
5858
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
5959
TOOLS := compiletest rustdoc rustc
@@ -69,11 +69,12 @@ DEPS_graphviz := std
6969
DEPS_green := std native:context_switch
7070
DEPS_native := std
7171
DEPS_syntax := std term serialize log fmt_macros arena libc
72+
DEPS_rustc_trans := rustc rustc_back rustc_llvm libc
7273
DEPS_rustc := syntax flate arena serialize getopts rbml \
7374
time log graphviz rustc_llvm rustc_back
7475
DEPS_rustc_llvm := native:rustllvm libc std
7576
DEPS_rustc_back := std syntax rustc_llvm flate log libc
76-
DEPS_rustdoc := rustc native:hoedown serialize getopts \
77+
DEPS_rustdoc := rustc rustc_trans native:hoedown serialize getopts \
7778
test time
7879
DEPS_flate := std native:miniz
7980
DEPS_arena := std
@@ -96,7 +97,7 @@ DEPS_fmt_macros = std
9697

9798
TOOL_DEPS_compiletest := test getopts native
9899
TOOL_DEPS_rustdoc := rustdoc native
99-
TOOL_DEPS_rustc := rustc native
100+
TOOL_DEPS_rustc := rustc_trans native
100101
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
101102
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
102103
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
@@ -112,8 +113,8 @@ ONLY_RLIB_unicode := 1
112113
# You should not need to edit below this line
113114
################################################################################
114115

115-
DOC_CRATES := $(filter-out rustc, $(filter-out syntax, $(CRATES)))
116-
COMPILER_DOC_CRATES := rustc syntax
116+
DOC_CRATES := $(filter-out rustc, $(filter-out rustc_trans, $(filter-out syntax, $(CRATES))))
117+
COMPILER_DOC_CRATES := rustc rustc_trans syntax
117118

118119
# This macro creates some simple definitions for each crate being built, just
119120
# some munging of all of the parameters above.

branches/snap-stage3/mk/docs.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
######################################################################
2828
DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
2929
guide-tasks guide-container guide-pointers guide-testing \
30-
guide-plugin guide-crates complement-bugreport \
30+
guide-plugin guide-crates complement-bugreport guide-error-handling \
3131
complement-lang-faq complement-design-faq complement-project-faq \
3232
rustdoc guide-unsafe guide-strings reference
3333

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
% Error Handling in Rust
2+
3+
> The best-laid plans of mice and men
4+
> Often go awry
5+
>
6+
> "Tae a Moose", Robert Burns
7+
8+
Sometimes, things just go wrong. It's important to have a plan for when the
9+
inevitable happens. Rust has rich support for handling errors that may (let's
10+
be honest: will) occur in your programs.
11+
12+
There are two main kinds of errors that can occur in your programs: failures,
13+
and panics. Let's talk about the difference between the two, and then discuss
14+
how to handle each. Then, we'll discuss upgrading failures to panics.
15+
16+
# Failure vs. Panic
17+
18+
Rust uses two terms to differentiate between two forms of error: failure, and
19+
panic. A **failure** is an error that can be recovered from in some way. A
20+
**panic** is an error that cannot be recovered from.
21+
22+
What do we mean by 'recover'? Well, in most cases, the possibility of an error
23+
is expected. For example, consider the `from_str` function:
24+
25+
```{rust,ignore}
26+
from_str("5");
27+
```
28+
29+
This function takes a string argument and converts it into another type. But
30+
because it's a string, you can't be sure that the conversion actually works.
31+
For example, what should this convert to?
32+
33+
```{rust,ignore}
34+
from_str("hello5world");
35+
```
36+
37+
This won't work. So we know that this function will only work properly for some
38+
inputs. It's expected behavior. We call this kind of error 'failure.'
39+
40+
On the other hand, sometimes, there are errors that are unexpected, or which
41+
we cannot recover from. A classic example is an `assert!`:
42+
43+
```{rust,ignore}
44+
assert!(x == 5);
45+
```
46+
47+
We use `assert!` to declare that something is true. If it's not true, something
48+
is very wrong. Wrong enough that we can't continue with things in the current
49+
state. Another example is using the `unreachable!()` macro
50+
51+
```{rust,ignore}
52+
enum Event {
53+
NewRelease,
54+
}
55+
56+
fn probability(_: &Event) -> f64 {
57+
// real implementation would be more complex, of course
58+
0.95
59+
}
60+
61+
fn descriptive_probability(event: Event) -> &'static str {
62+
match probability(&event) {
63+
1.00 => "certain",
64+
0.00 => "impossible",
65+
0.00 ... 0.25 => "very unlikely",
66+
0.25 ... 0.50 => "unlikely",
67+
0.50 ... 0.75 => "likely",
68+
0.75 ... 1.00 => "very likely",
69+
}
70+
}
71+
72+
fn main() {
73+
std::io::println(descriptive_probability(NewRelease));
74+
}
75+
```
76+
77+
This will give us an error:
78+
79+
```{notrust,ignore}
80+
error: non-exhaustive patterns: `_` not covered [E0004]
81+
```
82+
83+
While we know that we've covered all possible cases, Rust can't tell. It
84+
doesn't know that probability is between 0.0 and 1.0. So we add another case:
85+
86+
```rust
87+
enum Event {
88+
NewRelease,
89+
}
90+
91+
fn probability(_: &Event) -> f64 {
92+
// real implementation would be more complex, of course
93+
0.95
94+
}
95+
96+
fn descriptive_probability(event: Event) -> &'static str {
97+
match probability(&event) {
98+
1.00 => "certain",
99+
0.00 => "impossible",
100+
0.00 ... 0.25 => "very unlikely",
101+
0.25 ... 0.50 => "unlikely",
102+
0.50 ... 0.75 => "likely",
103+
0.75 ... 1.00 => "very likely",
104+
_ => unreachable!()
105+
}
106+
}
107+
108+
fn main() {
109+
std::io::println(descriptive_probability(NewRelease));
110+
}
111+
```
112+
113+
We shouldn't ever hit the `_` case, so we use the `unreachable!()` macro to
114+
indicate this. `unreachable!()` gives a different kind of error than `Result`.
115+
Rust calls these sorts of errors 'panics.'
116+
117+
# Handling errors with `Option` and `Result`
118+
119+
The simplest way to indicate that a function may fail is to use the `Option<T>`
120+
type. Remember our `from_str()` example? Here's its type signature:
121+
122+
```{rust,ignore}
123+
pub fn from_str<A: FromStr>(s: &str) -> Option<A>
124+
```
125+
126+
`from_str()` returns an `Option<A>`. If the conversion succeeds, it will return
127+
`Some(value)`, and if it fails, it will return `None`.
128+
129+
This is appropriate for the simplest of cases, but doesn't give us a lot of
130+
information in the failure case. What if we wanted to know _why_ the conversion
131+
failed? For this, we can use the `Result<T, E>` type. It looks like this:
132+
133+
```rust
134+
enum Result<T, E> {
135+
Ok(T),
136+
Err(E)
137+
}
138+
```
139+
140+
This enum is provided by Rust itself, so you don't need to define it to use it
141+
in your code. The `Ok(T)` variant represents a success, and the `Err(E)` variant
142+
represents a failure. Returning a `Result` instead of an `Option` is recommended
143+
for all but the most trivial of situations.
144+
145+
Here's an example of using `Result`:
146+
147+
```rust
148+
#[deriving(Show)]
149+
enum Version { Version1, Version2 }
150+
151+
#[deriving(Show)]
152+
enum ParseError { InvalidHeaderLength, InvalidVersion }
153+
154+
155+
fn parse_version(header: &[u8]) -> Result<Version, ParseError> {
156+
if header.len() < 1 {
157+
return Err(InvalidHeaderLength);
158+
}
159+
match header[0] {
160+
1 => Ok(Version1),
161+
2 => Ok(Version2),
162+
_ => Err(InvalidVersion)
163+
}
164+
}
165+
166+
let version = parse_version(&[1, 2, 3, 4]);
167+
match version {
168+
Ok(v) => {
169+
println!("working with version: {}", v);
170+
}
171+
Err(e) => {
172+
println!("error parsing header: {}", e);
173+
}
174+
}
175+
```
176+
177+
This function makes use of an enum, `ParseError`, to enumerate the various
178+
errors that can occur.
179+
180+
# Non-recoverable errors with `panic!`
181+
182+
In the case of an error that is unexpected and not recoverable, the `panic!`
183+
macro will induce a panic. This will crash the current task, and give an error:
184+
185+
```{rust,ignore}
186+
panic!("boom");
187+
```
188+
189+
gives
190+
191+
```{notrust,ignore}
192+
task '<main>' panicked at 'boom', hello.rs:2
193+
```
194+
195+
when you run it.
196+
197+
Because these kinds of situations are relatively rare, use panics sparingly.
198+
199+
# Upgrading failures to panics
200+
201+
In certain circumstances, even though a function may fail, we may want to treat
202+
it as a panic instead. For example, `io::stdin().read_line()` returns an
203+
`IoResult<String>`, a form of `Result`, when there is an error reading the
204+
line. This allows us to handle and possibly recover from this sort of error.
205+
206+
If we don't want to handle this error, and would rather just abort the program,
207+
we can use the `unwrap()` method:
208+
209+
```{rust,ignore}
210+
io::stdin().read_line().unwrap();
211+
```
212+
213+
`unwrap()` will `panic!` if the `Option` is `None`. This basically says "Give
214+
me the value, and if something goes wrong, just crash." This is less reliable
215+
than matching the error and attempting to recover, but is also significantly
216+
shorter. Sometimes, just crashing is appropriate.
217+
218+
There's another way of doing this that's a bit nicer than `unwrap()`:
219+
220+
```{rust,ignore}
221+
let input = io::stdin().read_line()
222+
.ok()
223+
.expect("Failed to read line");
224+
```
225+
`ok()` converts the `IoResult` into an `Option`, and `expect()` does the same
226+
thing as `unwrap()`, but takes a message. This message is passed along to the
227+
underlying `panic!`, providing a better error message if the code errors.

branches/snap-stage3/src/doc/guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ $ ./main # or main.exe on Windows
159159
Hello, world!
160160
```
161161

162+
You can also run these examples on [play.rust-lang.org](http://play.rust-lang.org/) by clicking on the arrow that appears in the upper right of the example when you mouse over the code.
163+
162164
Success! Let's go over what just happened in detail.
163165

164166
```{rust}

branches/snap-stage3/src/doc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ a guide that can help you out:
5959
* [References and Lifetimes](guide-lifetimes.html)
6060
* [Crates and modules](guide-crates.html)
6161
* [Tasks and Communication](guide-tasks.html)
62+
* [Error Handling](guide-error-handling.html)
6263
* [Foreign Function Interface](guide-ffi.html)
6364
* [Writing Unsafe and Low-Level Code](guide-unsafe.html)
6465
* [Macros](guide-macros.html)

branches/snap-stage3/src/doc/po4a.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
[type: text] src/doc/guide-testing.md $lang:doc/l10n/$lang/guide-testing.md
2121
[type: text] src/doc/guide-unsafe.md $lang:doc/l10n/$lang/guide-unsafe.md
2222
[type: text] src/doc/guide-crates.md $lang:doc/l10n/$lang/guide-crates.md
23+
[type: text] src/doc/guide-error-handling.md $lang:doc/l10n/$lang/guide-error-handling.md
2324
[type: text] src/doc/guide.md $lang:doc/l10n/$lang/guide.md
2425
[type: text] src/doc/index.md $lang:doc/l10n/$lang/index.md
2526
[type: text] src/doc/intro.md $lang:doc/l10n/$lang/intro.md

branches/snap-stage3/src/doc/reference.md

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,11 +2513,6 @@ The currently implemented features of the reference compiler are:
25132513
closure as `once` is unlikely to be supported going forward. So
25142514
they are hidden behind this feature until they are to be removed.
25152515

2516-
* `overloaded_calls` - Allow implementing the `Fn*` family of traits on user
2517-
types, allowing overloading the call operator (`()`).
2518-
This feature may still undergo changes before being
2519-
stabilized.
2520-
25212516
* `phase` - Usage of the `#[phase]` attribute allows loading compiler plugins
25222517
for custom lints or syntax extensions. The implementation is
25232518
considered unwholesome and in need of overhaul, and it is not clear
@@ -2560,11 +2555,8 @@ The currently implemented features of the reference compiler are:
25602555
* `trace_macros` - Allows use of the `trace_macros` macro, which is a nasty
25612556
hack that will certainly be removed.
25622557

2563-
* `unboxed_closure_sugar` - Allows using `|Foo| -> Bar` as a trait bound
2564-
meaning one of the `Fn` traits. Still
2565-
experimental.
2566-
2567-
* `unboxed_closures` - A work in progress feature with many known bugs.
2558+
* `unboxed_closures` - Rust's new closure design, which is currently a work in
2559+
progress feature with many known bugs.
25682560

25692561
* `unsafe_destructor` - Allows use of the `#[unsafe_destructor]` attribute,
25702562
which is considered wildly unsafe and will be
@@ -3565,17 +3557,14 @@ The machine types are the following:
35653557

35663558
#### Machine-dependent integer types
35673559

3568-
The Rust type `uint` [^rustuint] is an
3569-
unsigned integer type with target-machine-dependent size. Its size, in
3570-
bits, is equal to the number of bits required to hold any memory address on
3571-
the target machine.
3572-
3573-
The Rust type `int` [^rustint] is a two's complement signed integer type with
3574-
target-machine-dependent size. Its size, in bits, is equal to the size of the
3575-
rust type `uint` on the same target machine.
3560+
The `uint` type is an unsigned integer type with the same number of bits as the
3561+
platform's pointer type. It can represent every memory address in the process.
35763562

3577-
[^rustuint]: A Rust `uint` is analogous to a C99 `uintptr_t`.
3578-
[^rustint]: A Rust `int` is analogous to a C99 `intptr_t`.
3563+
The `int` type is a signed integer type with the same number of bits as the
3564+
platform's pointer type. The theoretical upper bound on object and array size
3565+
is the maximum `int` value. This ensures that `int` can be used to calculate
3566+
differences between pointers into an object or array and can address every byte
3567+
within an object along with one byte past the end.
35793568

35803569
### Textual types
35813570

branches/snap-stage3/src/driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
extern crate "rustdoc" as this;
1313

1414
#[cfg(rustc)]
15-
extern crate "rustc" as this;
15+
extern crate "rustc_trans" as this;
1616

1717
fn main() { this::main() }

0 commit comments

Comments
 (0)