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 x = std::ops::Range {start: 0, end: 10};
let y = 0..10; let y = 0..10;
assert_eq!(x,y); assert_eq!(x, y);
``` ```
### Unary operator expressions ### 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 a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a
label is present, then labeled `break` and `continue` expressions nested 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. 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). expressions](#continue-expressions).
### Break expressions ### `break` expressions
A `break` expression has an optional _label_. If the label is absent, then A `break` expression has an optional _label_. If the label is absent, then
executing a `break` expression immediately terminates the innermost loop 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 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. 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 A `continue` expression has an optional _label_. If the label is absent, then
executing a `continue` expression immediately terminates the current iteration 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. 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. A `while` loop begins by evaluating the boolean loop conditional expression.
If the loop conditional expression evaluates to `true`, the loop body block 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 loops](#infinite-loops), [break expressions](#break-expressions), and
[continue expressions](#continue-expressions) for more information. [continue expressions](#continue-expressions) for more information.
### For expressions ### `for` expressions
A `for` expression is a syntactic construct for looping over elements provided A `for` expression is a syntactic construct for looping over elements provided
by an implementation of `std::iter::IntoIterator`. 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; # 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 loops](#infinite-loops), [break expressions](#break-expressions), and
[continue expressions](#continue-expressions) for more information. [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 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 `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 if` condition is evaluated. If all `if` and `else if` conditions evaluate to
`false` then any `else` block is executed. `false` then any `else` block is executed.
### Match expressions ### `match` expressions
A `match` expression branches on a *pattern*. The exact form of matching that A `match` expression branches on a *pattern*. The exact form of matching that
occurs depends on the pattern. Patterns consist of some combination of 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 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 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 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 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. loop body block executes and control returns to the pattern matching statement.
Otherwise, the while expression completes. Otherwise, the while expression completes.
### Return expressions ### `return` expressions
Return expressions are denoted with the keyword `return`. Evaluating a `return` Return expressions are denoted with the keyword `return`. Evaluating a `return`
expression moves its argument into the designated output location for the 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 Here's another example that is slightly less contrived. A program that accepts
an integer as an argument, doubles it and prints it. an integer as an argument, doubles it and prints it.
<a name="code-unwrap-double"/>
```rust,should_panic ```rust,should_panic
use std::env; use std::env;
fn main() { 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` 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. 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]: 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 programmer to handle that absence. Let's take a look at an example that tries
to find a character in a string: to find a character in a string:
<a name="code-option-ex-string-find"/>
```rust ```rust
// Searches `haystack` for the Unicode character `needle`. If one is found, the // Searches `haystack` for the Unicode character `needle`. If one is found, the
// byte offset of the character is returned. Otherwise, `None` is returned. // 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 `Foo::Bar` or a `Foo::Baz`. We use the `::` to indicate the
namespace for a particular `enum` variant. 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 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 create an arm for each possible value. Since we have three types of
`Ordering`, we have three arms: `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 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` 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 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 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 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 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) * Windows (7, 8, Server 2008 R2)
* Linux (2.6.18 or later, various distributions), x86 and x86-64 * 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 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 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 it allocates some memory for the heap, and puts `5` there. The memory now looks
like this: like this:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 5 | | (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... | | ... | ... | ... |
| 1 | y | 42 | | 1 | y | 42 |
| 0 | x | → 2<sup>30</sup> | | 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 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 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 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. location weve asked for.
[rawpointer]: raw-pointers.html [rawpointer]: raw-pointers.html
@ -244,18 +244,18 @@ layout of a program which has been running for a while now:
| Address | Name | Value | | Address | Name | Value |
|----------------------|------|------------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 5 | | (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 1 | | |
| (2<sup>30</sup>) - 2 | | | | (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 | | 2 | y | 42 |
| 1 | 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 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 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 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. different memory allocators, which are libraries that manage this for you.
@ -366,29 +366,29 @@ fn main() {
First, we call `main()`: First, we call `main()`:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
We allocate memory for `j`, `i`, and `h`. `i` is on the heap, and so has a We allocate memory for `j`, `i`, and `h`. `i` is on the heap, and so has a
value pointing there. value pointing there.
Next, at the end of `main()`, `foo()` gets called: Next, at the end of `main()`, `foo()` gets called:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|-----------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 5 | z | → 4 | | 5 | z | → 4 |
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup>| | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
Space gets allocated for `x`, `y`, and `z`. The argument `x` has the same value 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, 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`: Next, `foo()` calls `baz()`, passing `z`:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 7 | g | 100 | | 7 | g | 100 |
| 6 | f | → 4 | | 6 | f | → 4 |
| 5 | z | → 4 | | 5 | z | → 4 |
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
Weve allocated memory for `f` and `g`. `baz()` is very short, so when its Weve allocated memory for `f` and `g`. `baz()` is very short, so when its
over, we get rid of its stack frame: over, we get rid of its stack frame:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 5 | z | → 4 | | 5 | z | → 4 |
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
Next, `foo()` calls `bar()` with `x` and `z`: Next, `foo()` calls `bar()` with `x` and `z`:
| Address | Name | Value | | Address | Name | Value |
|----------------------|------|------------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 1 | | 5 | | (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... | | ... | ... | ... |
| 10 | e | → 9 | | 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 | | 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 | | 8 | c | 5 |
| 7 | b | → 4 | | 7 | b | → 4 |
| 6 | a | → 0 | | 6 | a | → 0 |
@ -439,24 +439,24 @@ Next, `foo()` calls `bar()` with `x` and `z`:
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
We end up allocating another value on the heap, and so we have to subtract one 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. case, we set up the variables as usual.
At the end of `bar()`, it calls `baz()`: At the end of `bar()`, it calls `baz()`:
| Address | Name | Value | | Address | Name | Value |
|----------------------|------|------------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 1 | | 5 | | (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... | | ... | ... | ... |
| 12 | g | 100 | | 12 | g | 100 |
| 11 | f | → 9 | | 11 | f | → 9 |
| 10 | e | → 9 | | 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 | | 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 | | 8 | c | 5 |
| 7 | b | → 4 | | 7 | b | → 4 |
| 6 | a | → 0 | | 6 | a | → 0 |
@ -464,7 +464,7 @@ At the end of `bar()`, it calls `baz()`:
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
With this, were at our deepest point! Whew! Congrats for following along this 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 | | Address | Name | Value |
|----------------------|------|------------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 1 | | 5 | | (2<sup>30</sup>) - 2 | | 5 |
| ... | ... | ... | | ... | ... | ... |
| 10 | e | → 9 | | 10 | e | → 9 |
| 9 | d | → (2<sup>30</sup>) - 1 | | 9 | d | → (2<sup>30</sup>) - 2 |
| 8 | c | 5 | | 8 | c | 5 |
| 7 | b | → 4 | | 7 | b | → 4 |
| 6 | a | → 0 | | 6 | a | → 0 |
@ -486,32 +486,32 @@ After `baz()` is over, we get rid of `f` and `g`:
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
Next, we return from `bar()`. `d` in this case is a `Box<T>`, so it also frees 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 | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 5 | z | → 4 | | 5 | z | → 4 |
| 4 | y | 10 | | 4 | y | 10 |
| 3 | x | → 0 | | 3 | x | → 0 |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
And after that, `foo()` returns: And after that, `foo()` returns:
| Address | Name | Value | | Address | Name | Value |
|-----------------|------|------------------| |----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 | | (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... | | ... | ... | ... |
| 2 | j | → 0 | | 2 | j | → 0 |
| 1 | i | → 2<sup>30</sup> | | 1 | i | → (2<sup>30</sup>) - 1 |
| 0 | h | 3 | | 0 | h | 3 |
And then, finally, `main()`, which cleans the rest up. When `i` is `Drop`ped, And then, finally, `main()`, which cleans the rest up. When `i` is `Drop`ped,
it will clean up the last of the heap too. it will clean up the last of the heap too.

View File

@ -94,7 +94,7 @@ use fmt;
#[lang = "drop"] #[lang = "drop"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait Drop { 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")] #[stable(feature = "rust1", since = "1.0.0")]
fn drop(&mut self); 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 {} unsafe impl Sync for AtomicBool {}
/// A signed integer type which can be safely shared between threads. /// 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 {} unsafe impl Sync for AtomicIsize {}
/// An unsigned integer type which can be safely shared between threads. /// 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 {} unsafe impl Sync for AtomicUsize {}
/// A raw pointer type which can be safely shared between threads. /// 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();
}