Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Book: Small grammatical and stylistic edits to book #34532

Merged
merged 8 commits into from
Jul 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/doc/book/lifetimes.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ lifetime parameters using three easily memorizable and unambiguous rules. This m
acts as a shorthand for writing an item signature, while not hiding
away the actual types involved as full local inference would if applied to it.

When talking about lifetime elision, we use the term *input lifetime* and
When talking about lifetime elision, we use the terms *input lifetime* and
*output lifetime*. An *input lifetime* is a lifetime associated with a parameter
of a function, and an *output lifetime* is a lifetime associated with the return
value of a function. For example, this function has an input lifetime:
Expand Down Expand Up @@ -335,11 +335,13 @@ fn print<'a>(s: &'a str); // expanded

fn debug(lvl: u32, s: &str); // elided
fn debug<'a>(lvl: u32, s: &'a str); // expanded
```

// In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
// reference (`&`). Only things relating to references (such as a `struct`
// which contains a reference) need lifetimes.
In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
reference (`&`). Only things relating to references (such as a `struct`
which contains a reference) need lifetimes.

```rust,ignore
fn substr(s: &str, until: u32) -> &str; // elided
fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded

Expand Down
6 changes: 3 additions & 3 deletions src/doc/book/ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ 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´.
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.

Expand Down Expand Up @@ -288,6 +288,6 @@ let (v1, v2, answer) = foo(v1, v2);
Ugh! The return type, return line, and calling the function gets way more
complicated.

Luckily, Rust offers a feature, borrowing, which helps us solve this problem.
It’s the topic of the next section!
Luckily, Rust offers a feature which helps us solve this problem.
It’s called borrowing and is the topic of the next section!

44 changes: 24 additions & 20 deletions src/doc/book/references-and-borrowing.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ let v = vec![];
foo(&v);
```

errors with:
will give us this error:

```text
error: cannot borrow immutable borrowed content `*v` as mutable
Expand Down Expand Up @@ -152,8 +152,8 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
If it wasn’t, we couldn’t take a mutable borrow to an immutable value.

You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
this is because `y` is a `&mut` reference. You'll also need to use them for
accessing the contents of a reference as well.
this is because `y` is a `&mut` reference. You'll need to use astrisks to
access the contents of a reference as well.

Otherwise, `&mut` references are like references. There _is_ a large
difference between the two, and how they interact, though. You can tell
Expand All @@ -179,7 +179,7 @@ As it turns out, there are rules.

# The Rules

Here’s the rules about borrowing in Rust:
Here are the rules for borrowing in Rust:

First, any borrow must last for a scope no greater than that of the owner.
Second, you may have one or the other of these two kinds of borrows, but not
Expand Down Expand Up @@ -208,12 +208,14 @@ With this in mind, let’s consider our example again.
Here’s the code:

```rust,ignore
let mut x = 5;
let y = &mut x;
fn main() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we adding main here?

let mut x = 5;
let y = &mut x;

*y += 1;
*y += 1;

println!("{}", x);
println!("{}", x);
}
```

This code gives us this error:
Expand All @@ -225,7 +227,7 @@ error: cannot borrow `x` as immutable because it is also borrowed as mutable
```

This is because we’ve violated the rules: we have a `&mut T` pointing to `x`,
and so we aren’t allowed to create any `&T`s. One or the other. The note
and so we aren’t allowed to create any `&T`s. It's one or the other. The note
hints at how to think about this problem:

```text
Expand All @@ -243,14 +245,16 @@ In Rust, borrowing is tied to the scope that the borrow is valid for. And our
scopes look like this:

```rust,ignore
let mut x = 5;

let y = &mut x; // -+ &mut borrow of x starts here
// |
*y += 1; // |
// |
println!("{}", x); // -+ - try to borrow x here
// -+ &mut borrow of x ends here
fn main() {
let mut x = 5;

let y = &mut x; // -+ &mut borrow of x starts here
// |
*y += 1; // |
// |
println!("{}", x); // -+ - try to borrow x here
} // -+ &mut borrow of x ends here

```

The scopes conflict: we can’t make an `&x` while `y` is in scope.
Expand All @@ -269,12 +273,12 @@ println!("{}", x); // <- try to borrow x here
```

There’s no problem. Our mutable borrow goes out of scope before we create an
immutable one. But scope is the key to seeing how long a borrow lasts for.
immutable one. So scope is the key to seeing how long a borrow lasts for.

## Issues borrowing prevents

Why have these restrictive rules? Well, as we noted, these rules prevent data
races. What kinds of issues do data races cause? Here’s a few.
races. What kinds of issues do data races cause? Here are a few.

### Iterator invalidation

Expand Down Expand Up @@ -323,7 +327,7 @@ for i in &v {

We can’t modify `v` because it’s borrowed by the loop.

### use after free
### Use after free

References must not live longer than the resource they refer to. Rust will
check the scopes of your references to ensure that this is true.
Expand Down