Auto merge of #28476 - steveklabnik:rollup, r=steveklabnik

- Successful merges: #28276, #28314, #28422, #28435, #28451, #28466, #28470, #28471, #28473, #28474
- Failed merges:
This commit is contained in:
bors 2015-09-17 21:34:34 +00:00
commit cff0411706
8 changed files with 140 additions and 102 deletions

View File

@ -2762,7 +2762,7 @@ The following expressions are equivalent.
let x = std::ops::Range {start: 0, end: 10};
let y = 0..10;
assert_eq!(x,y);
assert_eq!(x, y);
```
### Unary operator expressions
@ -3035,10 +3035,10 @@ A `loop` expression may optionally have a _label_. The label is written as
a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a
label is present, then labeled `break` and `continue` expressions nested
within this loop may exit out of this loop or return control to its head.
See [Break expressions](#break-expressions) and [Continue
See [break expressions](#break-expressions) and [continue
expressions](#continue-expressions).
### Break expressions
### `break` expressions
A `break` expression has an optional _label_. If the label is absent, then
executing a `break` expression immediately terminates the innermost loop
@ -3046,7 +3046,7 @@ enclosing it. It is only permitted in the body of a loop. If the label is
present, then `break 'foo` terminates the loop with label `'foo`, which need not
be the innermost label enclosing the `break` expression, but must enclose it.
### Continue expressions
### `continue` expressions
A `continue` expression has an optional _label_. If the label is absent, then
executing a `continue` expression immediately terminates the current iteration
@ -3059,7 +3059,7 @@ innermost label enclosing the `break` expression, but must enclose it.
A `continue` expression is only permitted in the body of a loop.
### While loops
### `while` loops
A `while` loop begins by evaluating the boolean loop conditional expression.
If the loop conditional expression evaluates to `true`, the loop body block
@ -3082,12 +3082,12 @@ Like `loop` expressions, `while` loops can be controlled with `break` or
loops](#infinite-loops), [break expressions](#break-expressions), and
[continue expressions](#continue-expressions) for more information.
### For expressions
### `for` expressions
A `for` expression is a syntactic construct for looping over elements provided
by an implementation of `std::iter::IntoIterator`.
An example of a for loop over the contents of an array:
An example of a `for` loop over the contents of an array:
```
# type Foo = i32;
@ -3117,7 +3117,7 @@ Like `loop` expressions, `for` loops can be controlled with `break` or
loops](#infinite-loops), [break expressions](#break-expressions), and
[continue expressions](#continue-expressions) for more information.
### If expressions
### `if` expressions
An `if` expression is a conditional branch in program control. The form of an
`if` expression is a condition expression, followed by a consequent block, any
@ -3129,7 +3129,7 @@ evaluates to `false`, the consequent block is skipped and any subsequent `else
if` condition is evaluated. If all `if` and `else if` conditions evaluate to
`false` then any `else` block is executed.
### Match expressions
### `match` expressions
A `match` expression branches on a *pattern*. The exact form of matching that
occurs depends on the pattern. Patterns consist of some combination of
@ -3235,7 +3235,7 @@ let message = match maybe_digit {
};
```
### If let expressions
### `if let` expressions
An `if let` expression is semantically identical to an `if` expression but in place
of a condition expression it expects a refutable let statement. If the value of the
@ -3256,7 +3256,7 @@ if let ("Ham", b) = dish {
}
```
### While let loops
### `while let` loops
A `while let` loop is semantically identical to a `while` loop but in place of a
condition expression it expects a refutable let statement. If the value of the
@ -3264,7 +3264,7 @@ expression on the right hand side of the let statement matches the pattern, the
loop body block executes and control returns to the pattern matching statement.
Otherwise, the while expression completes.
### Return expressions
### `return` expressions
Return expressions are denoted with the keyword `return`. Evaluating a `return`
expression moves its argument into the designated output location for the

View File

@ -87,7 +87,9 @@ thread '<main>' panicked at 'Invalid number: 11', src/bin/panic-simple.rs:5
Here's another example that is slightly less contrived. A program that accepts
an integer as an argument, doubles it and prints it.
<a name="code-unwrap-double"/>
```rust,should_panic
use std::env;
fn main() {
@ -120,7 +122,7 @@ It would be better if we just showed the code for unwrapping because it is so
simple, but to do that, we will first need to explore the `Option` and `Result`
types. Both of these types have a method called `unwrap` defined on them.
## The `Option` type
### The `Option` type
The `Option` type is [defined in the standard library][5]:
@ -137,6 +139,7 @@ system is an important concept because it will cause the compiler to force the
programmer to handle that absence. Let's take a look at an example that tries
to find a character in a string:
<a name="code-option-ex-string-find"/>
```rust
// Searches `haystack` for the Unicode character `needle`. If one is found, the
// byte offset of the character is returned. Otherwise, `None` is returned.

View File

@ -599,7 +599,7 @@ With this definition, anything of type `Foo` can be either a
`Foo::Bar` or a `Foo::Baz`. We use the `::` to indicate the
namespace for a particular `enum` variant.
The [`Ordering`][ordering] enum has three possible variants: `Less`, `Equal`,
The [`Ordering`][ordering] `enum` has three possible variants: `Less`, `Equal`,
and `Greater`. The `match` statement takes a value of a type, and lets you
create an arm for each possible value. Since we have three types of
`Ordering`, we have three arms:
@ -918,9 +918,9 @@ let guess: u32 = match guess.trim().parse() {
This is how you generally move from crash on error to actually handle the
error, by switching from `ok().expect()` to a `match` statement. The `Result`
returned by `parse()` is an enum just like `Ordering`, but in this case, each
returned by `parse()` is an `enum` just like `Ordering`, but in this case, each
variant has some data associated with it: `Ok` is a success, and `Err` is a
failure. Each contains more information: the successful parsed integer, or an
failure. Each contains more information: the successfully parsed integer, or an
error type. In this case, we `match` on `Ok(num)`, which sets the inner value
of the `Ok` to the name `num`, and then we just return it on the right-hand
side. In the `Err` case, we dont care what kind of error it is, so we just

View File

@ -64,7 +64,7 @@ Oh, we should also mention the officially supported platforms:
* Windows (7, 8, Server 2008 R2)
* Linux (2.6.18 or later, various distributions), x86 and x86-64
* OSX 10.7 (Lion) or greater, x86 and x86-64
* OSX 10.7 (Lion) or later, x86 and x86-64
We extensively test Rust on these platforms, and a few others, too, like
Android. But these are the ones most likely to work, as they have the most

View File

@ -217,18 +217,18 @@ on the heap. The actual value of the box is a structure which has a pointer to
it allocates some memory for the heap, and puts `5` there. The memory now looks
like this:
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
| 0 | x | → 2<sup>30</sup> |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
| 0 | x | → (2<sup>30</sup>) - 1 |
We have 2<sup>30</sup> in our hypothetical computer with 1GB of RAM. And since
We have (2<sup>30</sup>) - 1 in our hypothetical computer with 1GB of RAM. And since
our stack grows from zero, the easiest place to allocate memory is from the
other end. So our first value is at the highest place in memory. And the value
of the struct at `x` has a [raw pointer][rawpointer] to the place weve
allocated on the heap, so the value of `x` is 2<sup>30</sup>, the memory
allocated on the heap, so the value of `x` is (2<sup>30</sup>) - 1, the memory
location weve asked for.
[rawpointer]: raw-pointers.html
@ -244,18 +244,18 @@ layout of a program which has been running for a while now:
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 5 |
| (2<sup>30</sup>) - 1 | | |
| (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 2 | | |
| (2<sup>30</sup>) - 3 | | 42 |
| (2<sup>30</sup>) - 3 | | |
| (2<sup>30</sup>) - 4 | | 42 |
| ... | ... | ... |
| 3 | y | → (2<sup>30</sup>) - 3 |
| 3 | y | → (2<sup>30</sup>) - 4 |
| 2 | y | 42 |
| 1 | y | 42 |
| 0 | x | → 2<sup>30</sup> |
| 0 | x | → (2<sup>30</sup>) - 1 |
In this case, weve allocated four things on the heap, but deallocated two of
them. Theres a gap between 2<sup>30</sup> and (2<sup>30</sup>) - 3 which isnt
them. Theres a gap between (2<sup>30</sup>) - 1 and (2<sup>30</sup>) - 4 which isnt
currently being used. The specific details of how and why this happens depends
on what kind of strategy you use to manage the heap. Different programs can use
different memory allocators, which are libraries that manage this for you.
@ -366,29 +366,29 @@ fn main() {
First, we call `main()`:
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
We allocate memory for `j`, `i`, and `h`. `i` is on the heap, and so has a
value pointing there.
Next, at the end of `main()`, `foo()` gets called:
| Address | Name | Value |
|-----------------|------|-----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup>|
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
Space gets allocated for `x`, `y`, and `z`. The argument `x` has the same value
as `j`, since thats what we passed it in. Its a pointer to the `0` address,
@ -396,42 +396,42 @@ since `j` points at `h`.
Next, `foo()` calls `baz()`, passing `z`:
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
| 6 | f | → 4 |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
| 6 | f | → 4 |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
Weve allocated memory for `f` and `g`. `baz()` is very short, so when its
over, we get rid of its stack frame:
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
Next, `foo()` calls `bar()` with `x` and `z`:
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... |
| 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 |
| 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 |
| 7 | b | → 4 |
| 6 | a | → 0 |
@ -439,24 +439,24 @@ Next, `foo()` calls `bar()` with `x` and `z`:
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
We end up allocating another value on the heap, and so we have to subtract one
from 2<sup>30</sup>. Its easier to just write that than `1,073,741,823`. In any
from (2<sup>30</sup>) - 1. Its easier to just write that than `1,073,741,822`. In any
case, we set up the variables as usual.
At the end of `bar()`, it calls `baz()`:
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... |
| 12 | g | 100 |
| 11 | f | → 9 |
| 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 |
| 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 |
| 7 | b | → 4 |
| 6 | a | → 0 |
@ -464,7 +464,7 @@ At the end of `bar()`, it calls `baz()`:
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
With this, were at our deepest point! Whew! Congrats for following along this
@ -474,11 +474,11 @@ After `baz()` is over, we get rid of `f` and `g`:
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... |
| 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 |
| 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 |
| 7 | b | → 4 |
| 6 | a | → 0 |
@ -486,32 +486,32 @@ After `baz()` is over, we get rid of `f` and `g`:
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
Next, we return from `bar()`. `d` in this case is a `Box<T>`, so it also frees
what it points to: (2<sup>30</sup>) - 1.
what it points to: (2<sup>30</sup>) - 2.
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
And after that, `foo()` returns:
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
| 2 | j | → 0 |
| 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 |
And then, finally, `main()`, which cleans the rest up. When `i` is `Drop`ped,
it will clean up the last of the heap too.

View File

@ -94,7 +94,7 @@ use fmt;
#[lang = "drop"]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Drop {
/// The `drop` method, called when the value goes out of scope.
/// A method called when the value goes out of scope.
#[stable(feature = "rust1", since = "1.0.0")]
fn drop(&mut self);
}

View File

@ -92,6 +92,7 @@ impl Default for AtomicBool {
}
}
// Send is implicitly implemented for AtomicBool.
unsafe impl Sync for AtomicBool {}
/// A signed integer type which can be safely shared between threads.
@ -106,6 +107,7 @@ impl Default for AtomicIsize {
}
}
// Send is implicitly implemented for AtomicIsize.
unsafe impl Sync for AtomicIsize {}
/// An unsigned integer type which can be safely shared between threads.
@ -120,6 +122,7 @@ impl Default for AtomicUsize {
}
}
// Send is implicitly implemented for AtomicUsize.
unsafe impl Sync for AtomicUsize {}
/// A raw pointer type which can be safely shared between threads.

View File

@ -0,0 +1,32 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::slice::Iter;
use std::io::{Error, ErrorKind, Result};
use std::vec::*;
fn foo(it: &mut Iter<u8>) -> Result<u8> {
Ok(*it.next().unwrap())
}
fn bar() -> Result<u8> {
let data: Vec<u8> = Vec::new();
if true {
return Err(Error::new(ErrorKind::NotFound, "msg"));
}
let mut it = data.iter();
foo(&mut it)
}
fn main() {
bar();
}