Auto merge of #26117 - Manishearth:rollup, r=Manishearth

- Successful merges: #25898, #25909, #25948, #25968, #26073, #26078, #26099, #26104, #26105, #26112, #26113
- Failed merges:
This commit is contained in:
bors 2015-06-09 01:34:24 +00:00
commit a35ea4d358
14 changed files with 85 additions and 36 deletions

View File

@ -1038,7 +1038,7 @@ be undesired.
* Deadlocks
* Reading data from private fields (`std::repr`)
* Leaks due to reference count cycles, even in the global heap
* Leaks of memory and other resources
* Exiting without calling destructors
* Sending signals
* Accessing/modifying the file system
@ -1418,9 +1418,13 @@ impl<T> Container for Vec<T> {
```
Generic functions may use traits as _bounds_ on their type parameters. This
will have two effects: only types that have the trait may instantiate the
parameter, and within the generic function, the methods of the trait can be
called on values that have the parameter's type. For example:
will have two effects:
- Only types that have the trait may instantiate the parameter.
- Within the generic function, the methods of the trait can be
called on values that have the parameter's type.
For example:
```
# type Surface = i32;
@ -2831,13 +2835,13 @@ on the right-hand side.
An example of an `as` expression:
```
# fn sum(v: &[f64]) -> f64 { 0.0 }
# fn len(v: &[f64]) -> i32 { 0 }
# fn sum(values: &[f64]) -> f64 { 0.0 }
# fn len(values: &[f64]) -> i32 { 0 }
fn avg(v: &[f64]) -> f64 {
let sum: f64 = sum(v);
let sz: f64 = len(v) as f64;
return sum / sz;
fn average(values: &[f64]) -> f64 {
let sum: f64 = sum(values);
let size: f64 = len(values) as f64;
sum / size
}
```

View File

@ -33,8 +33,8 @@ let plus_two = |x| {
assert_eq!(4, plus_two(2));
```
Youll notice a few things about closures that are a bit different than regular
functions defined with `fn`. The first of which is that we did not need to
Youll notice a few things about closures that are a bit different from regular
functions defined with `fn`. The first is that we did not need to
annotate the types of arguments the closure takes or the values it returns. We
can:
@ -48,10 +48,10 @@ But we dont have to. Why is this? Basically, it was chosen for ergonomic reas
While specifying the full type for named functions is helpful with things like
documentation and type inference, the types of closures are rarely documented
since theyre anonymous, and they dont cause the kinds of error-at-a-distance
that inferring named function types can.
problems that inferring named function types can.
The second is that the syntax is similar, but a bit different. Ive added spaces
here to make them look a little closer:
here for easier comparison:
```rust
fn plus_one_v1 (x: i32) -> i32 { x + 1 }
@ -59,7 +59,7 @@ let plus_one_v2 = |x: i32| -> i32 { x + 1 };
let plus_one_v3 = |x: i32| x + 1 ;
```
Small differences, but theyre similar in ways.
Small differences, but theyre similar.
# Closures and their environment
@ -99,7 +99,7 @@ note: previous borrow ends here
fn main() {
let mut num = 5;
let plus_num = |x| x + num;
let y = &mut num;
}
^
@ -161,7 +161,7 @@ of `num`. So whats the difference?
```rust
let mut num = 5;
{
{
let mut add_num = |x: i32| num += x;
add_num(5);
@ -180,7 +180,7 @@ If we change to a `move` closure, its different:
```rust
let mut num = 5;
{
{
let mut add_num = move |x: i32| num += x;
add_num(5);

View File

@ -29,6 +29,9 @@ The other kind of comment is a doc comment. Doc comments use `///` instead of
/// let five = 5;
///
/// assert_eq!(6, add_one(5));
/// # fn add_one(x: i32) -> i32 {
/// # x + 1
/// # }
/// ```
fn add_one(x: i32) -> i32 {
x + 1

View File

@ -432,7 +432,9 @@ an extra annotation, `move`, to indicate that the closure is going to take
ownership of the values its capturing. Primarily, the `p` variable of the
`map` function.
Inside the thread, all we do is call `eat()` on `p`.
Inside the thread, all we do is call `eat()` on `p`. Also note that the call to `thread::spawn` lacks a trailing semicolon, making this an expression. This distinction is important, yielding the correct return value. For more details, read [Expressions vs. Statements][es].
[es]: functions.html#expressions-vs.-statements
```rust,ignore
}).collect();

View File

@ -284,7 +284,7 @@ struct Info {
}
fn write_info(info: &Info) -> io::Result<()> {
let mut file = try!(File::create("my_best_friends.txt"));
let mut file = File::create("my_best_friends.txt").unwrap();
try!(writeln!(&mut file, "name: {}", info.name));
try!(writeln!(&mut file, "age: {}", info.age));

View File

@ -1,8 +1,8 @@
% Generics
Sometimes, when writing a function or data type, we may want it to work for
multiple types of arguments. Luckily, Rust has a feature that gives us a better
way: generics. Generics are called parametric polymorphism in type theory,
multiple types of arguments. In Rust, we can do this with generics.
Generics are called parametric polymorphism in type theory,
which means that they are types or functions that have multiple forms (poly
is multiple, morph is form) over a given parameter (parametric).

View File

@ -36,7 +36,7 @@ Note that since we're creating an executable, we used `main.rs`. If we
want to make a library instead, we should use `lib.rs`. This convention is required
for Cargo to successfully compile our projects, but it can be overridden if we wish.
Custom file locations for the entry point can be specified
with a [`[[lib]]` or `[[bin]]`][crates-custom] key in the TOML file described below.
with a [`[lib]` or `[[bin]]`][crates-custom] key in the TOML file.
[crates-custom]: http://doc.crates.io/manifest.html#configuring-a-target

View File

@ -156,6 +156,46 @@ that, just like a move, when we assign `v` to `v2`, a copy of the data is made.
But, unlike a move, we can still use `v` afterward. This is because an `i32`
has no pointers to data somewhere else, copying it is a full copy.
All primitive types implement the `Copy` trait and their ownership is
therefore not moved like one would assume, following the ´ownership rules´.
To give an example, the two following snippets of code only compile because the
`i32` and `bool` types implement the `Copy` trait.
```rust
fn main() {
let a = 5;
let _y = double(a);
println!("{}", a);
}
fn double(x: i32) -> i32 {
x * 2
}
```
```rust
fn main() {
let a = true;
let _y = change_truth(a);
println!("{}", a);
}
fn change_truth(x: bool) -> bool {
!x
}
```
If we would have used types that do not implement the `Copy` trait,
we would have gotten a compile error because we tried to use a moved value.
```text
error: use of moved value: `a`
println!("{}", a);
^
```
We will discuss how to make your own types `Copy` in the [traits][traits]
section.

View File

@ -261,7 +261,7 @@ static Foo_for_String_vtable: FooVtable = FooVtable {
```
The `destructor` field in each vtable points to a function that will clean up
any resources of the vtables type, for `u8` it is trivial, but for `String` it
any resources of the vtables type: for `u8` it is trivial, but for `String` it
will free the memory. This is necessary for owning trait objects like
`Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
internal type when they go out of scope. The `size` and `align` fields store
@ -270,7 +270,7 @@ essentially unused at the moment since the information is embedded in the
destructor, but will be used in the future, as trait objects are progressively
made more flexible.
Suppose weve got some values that implement `Foo`, then the explicit form of
Suppose weve got some values that implement `Foo`. The explicit form of
construction and use of `Foo` trait objects might look a bit like (ignoring the
type mismatches: theyre all just pointers anyway):

View File

@ -45,7 +45,7 @@ but we dont define a body, just a type signature. When we `impl` a trait,
we use `impl Trait for Item`, rather than just `impl Item`.
We can use traits to constrain our generics. Consider this function, which
does not compile, and gives us a similar error:
does not compile:
```rust,ignore
fn print_area<T>(shape: T) {
@ -56,7 +56,7 @@ fn print_area<T>(shape: T) {
Rust complains:
```text
error: type `T` does not implement any method in scope named `area`
error: no method named `area` found for type `T` in the current scope
```
Because `T` can be any type, we cant be sure that it implements the `area`
@ -212,10 +212,10 @@ This will compile without error.
This means that even if someone does something bad like add methods to `i32`,
it wont affect you, unless you `use` that trait.
Theres one more restriction on implementing traits. Either the trait or the
type youre writing the `impl` for must be defined by you. So, we could
Theres one more restriction on implementing traits: either the trait, or the
type youre writing the `impl` for, must be defined by you. So, we could
implement the `HasArea` type for `i32`, because `HasArea` is in our code. But
if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could
if we tried to implement `ToString`, a trait provided by Rust, for `i32`, we could
not, because neither the trait nor the type are in our code.
One last thing about traits: generic functions with a trait bound use

View File

@ -1663,11 +1663,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
ty::ty_vec(element_ty, ref len) => {
// [T, ..n] and [T]
// [T; n] and [T]
match bound {
ty::BoundCopy => {
match *len {
// [T, ..n] is copy iff T is copy
// [T; n] is copy iff T is copy
Some(_) => ok_if(vec![element_ty]),
// [T] is unsized and hence affine

View File

@ -234,8 +234,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
}
// &[T, ..n] or &mut [T, ..n] -> &[T]
// or &mut [T, ..n] -> &mut [T]
// &[T; n] or &mut [T; n] -> &[T]
// or &mut [T; n] -> &mut [T]
// or &Concrete -> &Trait, etc.
fn coerce_unsized(&self,
source: Ty<'tcx>,

View File

@ -18,7 +18,7 @@ into a more explicit UFCS form:
Here `ADJ` is some kind of adjustment, which is typically a series of
autoderefs and then possibly an autoref (e.g., `&**receiver`). However
we sometimes do other adjustments and coercions along the way, in
particular unsizing (e.g., converting from `[T, ..n]` to `[T]`).
particular unsizing (e.g., converting from `[T; n]` to `[T]`).
## The Two Phases

View File

@ -2085,7 +2085,7 @@ fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
return final_mt;
}
// After we have fully autoderef'd, if the resulting type is [T, ..n], then
// After we have fully autoderef'd, if the resulting type is [T; n], then
// do a final unsized coercion to yield [T].
if let ty::ty_vec(element_ty, Some(_)) = ty.sty {
let adjusted_ty = ty::mk_vec(fcx.tcx(), element_ty, None);