diff --git a/src/doc/reference.md b/src/doc/reference.md index d56ecb360cfed..875a65e69fa9f 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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 Container for Vec { ``` 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 } ``` diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index d2fe9c6e550c9..4479fdb7baae5 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.md @@ -33,8 +33,8 @@ let plus_two = |x| { assert_eq!(4, plus_two(2)); ``` -You’ll 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 +You’ll 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 don’t 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 they’re anonymous, and they don’t 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. I’ve 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 they’re similar in ways. +Small differences, but they’re 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 what’s 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, it’s different: ```rust let mut num = 5; -{ +{ let mut add_num = move |x: i32| num += x; add_num(5); diff --git a/src/doc/trpl/comments.md b/src/doc/trpl/comments.md index fa27d1c226cc4..7687d2a57da92 100644 --- a/src/doc/trpl/comments.md +++ b/src/doc/trpl/comments.md @@ -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 diff --git a/src/doc/trpl/dining-philosophers.md b/src/doc/trpl/dining-philosophers.md index 7e37473ac8fea..a18d9bb442dd2 100644 --- a/src/doc/trpl/dining-philosophers.md +++ b/src/doc/trpl/dining-philosophers.md @@ -432,7 +432,9 @@ an extra annotation, `move`, to indicate that the closure is going to take ownership of the values it’s 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(); diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 7b47559e0fce0..2a0e8ed16436e 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -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)); diff --git a/src/doc/trpl/generics.md b/src/doc/trpl/generics.md index f8f1962e0cf55..c28d7c71608bb 100644 --- a/src/doc/trpl/generics.md +++ b/src/doc/trpl/generics.md @@ -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’). diff --git a/src/doc/trpl/hello-cargo.md b/src/doc/trpl/hello-cargo.md index 0e5bbea453c6e..9920e8e00685b 100644 --- a/src/doc/trpl/hello-cargo.md +++ b/src/doc/trpl/hello-cargo.md @@ -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 diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 0ba2b33759cd5..46af311acf315 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -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. diff --git a/src/doc/trpl/trait-objects.md b/src/doc/trpl/trait-objects.md index c01129057418c..3da29c9b817d2 100644 --- a/src/doc/trpl/trait-objects.md +++ b/src/doc/trpl/trait-objects.md @@ -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 vtable’s type, for `u8` it is trivial, but for `String` it +any resources of the vtable’s type: for `u8` it is trivial, but for `String` it will free the memory. This is necessary for owning trait objects like `Box`, 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 we’ve got some values that implement `Foo`, then the explicit form of +Suppose we’ve 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: they’re all just pointers anyway): diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 2ef9e7ca22e60..162a2db1ec754 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -45,7 +45,7 @@ but we don’t 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(shape: T) { @@ -56,7 +56,7 @@ fn print_area(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 can’t 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 won’t affect you, unless you `use` that trait. -There’s one more restriction on implementing traits. Either the trait or the -type you’re writing the `impl` for must be defined by you. So, we could +There’s one more restriction on implementing traits: either the trait, or the +type you’re 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 diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 4ea6f0cb26ea0..789d4f8b9d310 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -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 diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 92317aae08967..624312dac3873 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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>, diff --git a/src/librustc_typeck/check/method/README.md b/src/librustc_typeck/check/method/README.md index 367273dc635f4..b5d317d602538 100644 --- a/src/librustc_typeck/check/method/README.md +++ b/src/librustc_typeck/check/method/README.md @@ -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 diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e37856bbb2ea2..6f97239ae939e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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);