Skip to content

Commit a99d3a8

Browse files
committed
---
yaml --- r: 161135 b: refs/heads/snap-stage3 c: f530aa0 h: refs/heads/master i: 161133: a9aca29 161131: cb86aa4 161127: 8873c90 161119: 438c0af v: v3
1 parent fbc3b3e commit a99d3a8

File tree

315 files changed

+8690
-13811
lines changed

Some content is hidden

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

315 files changed

+8690
-13811
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: 4eb72d268f337a8f117c86a2ac1b98336cab9e9d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 62a2a1d5cf4af0307f538a9bedb40e5756e89fb6
4+
refs/heads/snap-stage3: f530aa08dfcdaeb249341bdd1a9797780b4294c2
55
refs/heads/try: 0f0d21c1eb5c7be04d323e0b06faf252ad790af6
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d

branches/snap-stage3/configure

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,19 @@ CFG_LIBDIR_RELATIVE=lib
550550
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ]
551551
then
552552
CFG_LIBDIR_RELATIVE=bin
553-
fi
553+
CFG_LIBDIR="${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}"
554+
else
555+
valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries (ignored on windows platform)"
556+
557+
case "$CFG_LIBDIR" in
558+
"$CFG_PREFIX"/*) CAT_INC=2;;
559+
"$CFG_PREFIX"*) CAT_INC=1;;
560+
*)
561+
err "libdir must begin with the prefix. Use --prefix to set it accordingly.";;
562+
esac
554563

555-
valopt libdir "${CFG_PREFIX}/${CFG_LIBDIR_RELATIVE}" "install libraries"
564+
CFG_LIBDIR_RELATIVE=`echo ${CFG_LIBDIR} | cut -c$((${#CFG_PREFIX}+${CAT_INC}))-`
565+
fi
556566

557567
if [ $HELP -eq 1 ]
558568
then
@@ -989,6 +999,15 @@ for h in $CFG_HOST
989999
do
9901000
for t in $CFG_TARGET
9911001
do
1002+
# host lib dir stage0
1003+
make_dir $h/stage0/lib
1004+
1005+
# target bin dir stage0
1006+
make_dir $h/stage0/lib/rustlib/$t/bin
1007+
1008+
# target lib dir stage0
1009+
make_dir $h/stage0/lib/rustlib/$t/lib
1010+
9921011
for i in 0 1 2 3
9931012
do
9941013
# host bin dir
@@ -1031,6 +1050,7 @@ do
10311050
make_dir $h/test/doc-guide-tasks
10321051
make_dir $h/test/doc-guide-plugin
10331052
make_dir $h/test/doc-guide-crates
1053+
make_dir $h/test/doc-guide-error-handling
10341054
make_dir $h/test/doc-rust
10351055
done
10361056

branches/snap-stage3/mk/crates.mk

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#
3838
# DEPS_<crate>
3939
# These lists are the dependencies of the <crate> that is to be built.
40-
# Rust dependencies are listed bare (i.e. std, green) and native
40+
# Rust dependencies are listed bare (i.e. std) and native
4141
# dependencies have a "native:" prefix (i.e. native:hoedown). All deps
4242
# will be built before the crate itself is built.
4343
#
@@ -49,7 +49,7 @@
4949
# automatically generated for all stage/host/target combinations.
5050
################################################################################
5151

52-
TARGET_CRATES := libc std green native flate arena term \
52+
TARGET_CRATES := libc std flate arena term \
5353
serialize sync getopts collections test time rand \
5454
log regex graphviz core rbml alloc rustrt \
5555
unicode
@@ -66,8 +66,6 @@ DEPS_rustrt := alloc core libc collections native:rustrt_native
6666
DEPS_std := core libc rand alloc collections rustrt sync unicode \
6767
native:rust_builtin native:backtrace
6868
DEPS_graphviz := std
69-
DEPS_green := std native:context_switch
70-
DEPS_native := std
7169
DEPS_syntax := std term serialize log fmt_macros arena libc
7270
DEPS_rustc_trans := rustc rustc_back rustc_llvm libc
7371
DEPS_rustc := syntax flate arena serialize getopts rbml \
@@ -95,9 +93,9 @@ DEPS_regex := std
9593
DEPS_regex_macros = rustc syntax std regex
9694
DEPS_fmt_macros = std
9795

98-
TOOL_DEPS_compiletest := test getopts native
99-
TOOL_DEPS_rustdoc := rustdoc native
100-
TOOL_DEPS_rustc := rustc_trans native
96+
TOOL_DEPS_compiletest := test getopts
97+
TOOL_DEPS_rustdoc := rustdoc
98+
TOOL_DEPS_rustc := rustc_trans
10199
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
102100
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
103101
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs

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

branches/snap-stage3/mk/grammar.mk

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,25 @@ endef
3030
$(BG):
3131
$(Q)mkdir -p $(BG)
3232

33-
$(BG)RustLexer.class: $(SG)RustLexer.g4
33+
$(BG)RustLexer.class: $(BG) $(SG)RustLexer.g4
3434
$(Q)$(CFG_ANTLR4) -o $(B)grammar $(SG)RustLexer.g4
3535
$(Q)$(CFG_JAVAC) -d $(BG) $(BG)RustLexer.java
3636

37-
$(BG)verify: $(SG)verify.rs rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.regex_macros $(LD)stamp.rustc
38-
$(Q)$(RUSTC) -O --out-dir $(BG) -L $(L) $(SG)verify.rs
37+
check-build-lexer-verifier: $(BG)verify
38+
39+
ifeq ($(NO_REBUILD),)
40+
VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.regex_macros $(LD)stamp.rustc
41+
else
42+
VERIFY_DEPS :=
43+
endif
44+
45+
$(BG)verify: $(BG) $(SG)verify.rs $(VERIFY_DEPS)
46+
$(Q)$(RUSTC) --out-dir $(BG) -L $(L) $(SG)verify.rs
3947

4048
ifdef CFG_JAVAC
4149
ifdef CFG_ANTLR4
4250
ifdef CFG_GRUN
43-
check-lexer: $(BG) $(BG)RustLexer.class $(BG)verify
51+
check-lexer: $(BG) $(BG)RustLexer.class check-build-lexer-verifier
4452
$(info Verifying libsyntax against the reference lexer ...)
4553
$(Q)$(SG)check.sh $(S) "$(BG)" \
4654
"$(CFG_GRUN)" "$(BG)verify" "$(BG)RustLexer.tokens"

branches/snap-stage3/mk/main.mk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,15 @@ define SREQ
332332
# Destinations of artifacts for the host compiler
333333
HROOT$(1)_H_$(3) = $(3)/stage$(1)
334334
HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin
335+
ifeq ($$(CFG_WINDOWSY_$(3)),1)
335336
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE)
337+
else
338+
ifeq ($(1),0)
339+
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/lib
340+
else
341+
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE)
342+
endif
343+
endif
336344

337345
# Destinations of artifacts for target architectures
338346
TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustlib/$(2)

branches/snap-stage3/mk/tests.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ check-docs: cleantestlibs cleantmptestlogs check-stage2-docs
199199

200200
# Some less critical tests that are not prone to breakage.
201201
# Not run as part of the normal test suite, but tested by bors on checkin.
202-
check-secondary: check-build-compiletest check-lexer check-pretty
202+
check-secondary: check-build-compiletest check-build-lexer-verifier check-lexer check-pretty
203203

204204
# check + check-secondary.
205205
#

branches/snap-stage3/src/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ Source layout:
99
| `libcore/` | The Rust core library |
1010
| `libdebug/` | Debugging utilities |
1111
| `libstd/` | The standard library (imported and linked by default) |
12-
| `libgreen/` | The M:N runtime library |
13-
| `libnative/` | The 1:1 runtime library |
1412
| `libsyntax/` | The Rust parser and pretty-printer |
1513
| `libtest/` | Rust's test-runner code |
1614
| ------------------- | --------------------------------------------------------- |
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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+
use Event::NewRelease;
88+
89+
enum Event {
90+
NewRelease,
91+
}
92+
93+
fn probability(_: &Event) -> f64 {
94+
// real implementation would be more complex, of course
95+
0.95
96+
}
97+
98+
fn descriptive_probability(event: Event) -> &'static str {
99+
match probability(&event) {
100+
1.00 => "certain",
101+
0.00 => "impossible",
102+
0.00 ... 0.25 => "very unlikely",
103+
0.25 ... 0.50 => "unlikely",
104+
0.50 ... 0.75 => "likely",
105+
0.75 ... 1.00 => "very likely",
106+
_ => unreachable!()
107+
}
108+
}
109+
110+
fn main() {
111+
println!("{}", descriptive_probability(NewRelease));
112+
}
113+
```
114+
115+
We shouldn't ever hit the `_` case, so we use the `unreachable!()` macro to
116+
indicate this. `unreachable!()` gives a different kind of error than `Result`.
117+
Rust calls these sorts of errors 'panics.'
118+
119+
# Handling errors with `Option` and `Result`
120+
121+
The simplest way to indicate that a function may fail is to use the `Option<T>`
122+
type. Remember our `from_str()` example? Here's its type signature:
123+
124+
```{rust,ignore}
125+
pub fn from_str<A: FromStr>(s: &str) -> Option<A>
126+
```
127+
128+
`from_str()` returns an `Option<A>`. If the conversion succeeds, it will return
129+
`Some(value)`, and if it fails, it will return `None`.
130+
131+
This is appropriate for the simplest of cases, but doesn't give us a lot of
132+
information in the failure case. What if we wanted to know _why_ the conversion
133+
failed? For this, we can use the `Result<T, E>` type. It looks like this:
134+
135+
```rust
136+
enum Result<T, E> {
137+
Ok(T),
138+
Err(E)
139+
}
140+
```
141+
142+
This enum is provided by Rust itself, so you don't need to define it to use it
143+
in your code. The `Ok(T)` variant represents a success, and the `Err(E)` variant
144+
represents a failure. Returning a `Result` instead of an `Option` is recommended
145+
for all but the most trivial of situations.
146+
147+
Here's an example of using `Result`:
148+
149+
```rust
150+
#[deriving(Show)]
151+
enum Version { Version1, Version2 }
152+
153+
#[deriving(Show)]
154+
enum ParseError { InvalidHeaderLength, InvalidVersion }
155+
156+
fn parse_version(header: &[u8]) -> Result<Version, ParseError> {
157+
if header.len() < 1 {
158+
return Err(ParseError::InvalidHeaderLength);
159+
}
160+
match header[0] {
161+
1 => Ok(Version::Version1),
162+
2 => Ok(Version::Version2),
163+
_ => Err(ParseError::InvalidVersion)
164+
}
165+
}
166+
167+
let version = parse_version(&[1, 2, 3, 4]);
168+
match version {
169+
Ok(v) => {
170+
println!("working with version: {}", v);
171+
}
172+
Err(e) => {
173+
println!("error parsing header: {}", e);
174+
}
175+
}
176+
```
177+
178+
This function makes use of an enum, `ParseError`, to enumerate the various
179+
errors that can occur.
180+
181+
# Non-recoverable errors with `panic!`
182+
183+
In the case of an error that is unexpected and not recoverable, the `panic!`
184+
macro will induce a panic. This will crash the current task, and give an error:
185+
186+
```{rust,ignore}
187+
panic!("boom");
188+
```
189+
190+
gives
191+
192+
```{notrust,ignore}
193+
task '<main>' panicked at 'boom', hello.rs:2
194+
```
195+
196+
when you run it.
197+
198+
Because these kinds of situations are relatively rare, use panics sparingly.
199+
200+
# Upgrading failures to panics
201+
202+
In certain circumstances, even though a function may fail, we may want to treat
203+
it as a panic instead. For example, `io::stdin().read_line()` returns an
204+
`IoResult<String>`, a form of `Result`, when there is an error reading the
205+
line. This allows us to handle and possibly recover from this sort of error.
206+
207+
If we don't want to handle this error, and would rather just abort the program,
208+
we can use the `unwrap()` method:
209+
210+
```{rust,ignore}
211+
io::stdin().read_line().unwrap();
212+
```
213+
214+
`unwrap()` will `panic!` if the `Option` is `None`. This basically says "Give
215+
me the value, and if something goes wrong, just crash." This is less reliable
216+
than matching the error and attempting to recover, but is also significantly
217+
shorter. Sometimes, just crashing is appropriate.
218+
219+
There's another way of doing this that's a bit nicer than `unwrap()`:
220+
221+
```{rust,ignore}
222+
let input = io::stdin().read_line()
223+
.ok()
224+
.expect("Failed to read line");
225+
```
226+
`ok()` converts the `IoResult` into an `Option`, and `expect()` does the same
227+
thing as `unwrap()`, but takes a message. This message is passed along to the
228+
underlying `panic!`, providing a better error message if the code errors.

0 commit comments

Comments
 (0)