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

(Mini) Rollup of 15 pull requests #23660

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0c040b0
guide: minor copy edits
ches Mar 2, 2015
92294e7
guide: Improvements to language covering enums
ches Mar 2, 2015
c175b35
fix the attributes sytax
FuGangqiang Mar 21, 2015
bc9d9f2
add lifetime for `while` and `for` expression
FuGangqiang Mar 21, 2015
90c8592
Refine Cursor docstring
nagisa Mar 22, 2015
5321d22
Remove bad reference to std::io
steveklabnik Mar 22, 2015
fbc823d
Document how to document macros
steveklabnik Mar 22, 2015
81801f2
Re-word explanation on closures in intro
steveklabnik Mar 22, 2015
d944689
Fix dead link for std::sync::mpsc.
WiSaGaN Mar 23, 2015
2750e3c
Add note about pointer state after the call.
steveklabnik Mar 20, 2015
d6fb7e9
derive missing trait implementations for cursor
mahkoh Mar 22, 2015
a5e1cbe
Beef up BufRead::consume documentation.
steveklabnik Mar 22, 2015
d52c362
Clarify that slices don't just point to arrays
steveklabnik Mar 23, 2015
05c9728
Don't conflate regions and affine types
steveklabnik Mar 23, 2015
1be8fcb
Make note of str in 'more strings' chapter
steveklabnik Mar 23, 2015
248b2ec
Stabilize Entry types
aturon Mar 19, 2015
3f52d71
Update docs for ptr module.
mbrubeck Mar 23, 2015
1f984c6
Rollup merge of #22954 - ches:docs, r=steveklabnik
Manishearth Mar 24, 2015
413c0c9
Rollup merge of #23509 - aturon:stab-entry, r=aturon
Manishearth Mar 24, 2015
566becb
Rollup merge of #23561 - steveklabnik:gh23422, r=alexcrichton
Manishearth Mar 24, 2015
2b19ddb
Rollup merge of #23590 - FuGangqiang:attr, r=alexcrichton
Manishearth Mar 24, 2015
847118f
Rollup merge of #23607 - mahkoh:cursor, r=alexcrichton
Manishearth Mar 24, 2015
cc76e09
Rollup merge of #23608 - nagisa:refine-cursor-docstring, r=steveklabnik
Manishearth Mar 24, 2015
3a021fa
Rollup merge of #23615 - steveklabnik:gh23540, r=alexcrichton
Manishearth Mar 24, 2015
01e94e7
Rollup merge of #23618 - steveklabnik:gh23571, r=alexcrichton
Manishearth Mar 24, 2015
b5e841b
Rollup merge of #23619 - steveklabnik:gh23220, r=alexcrichton
Manishearth Mar 24, 2015
408e6bd
Rollup merge of #23622 - steveklabnik:gh23196, r=alexcrichton
Manishearth Mar 24, 2015
10ab1cb
Rollup merge of #23634 - WiSaGaN:bugfix/fix_dead_link, r=steveklabnik
Manishearth Mar 24, 2015
0175198
Rollup merge of #23639 - steveklabnik:gh21305, r=alexcrichton
Manishearth Mar 24, 2015
12c7e37
Rollup merge of #23641 - steveklabnik:gh23632, r=alexcrichton
Manishearth Mar 24, 2015
4c11af4
Rollup merge of #23644 - mbrubeck:doc-edit, r=steveklabnik
Manishearth Mar 24, 2015
01a7947
Rollup merge of #23645 - steveklabnik:gh23642, r=brson
Manishearth Mar 24, 2015
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
20 changes: 10 additions & 10 deletions src/doc/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,16 +446,16 @@ It gives us this error:
error: aborting due to previous error
```

It mentions that "captured outer variable in an `FnMut` closure".
Because we declared the closure as a moving closure, and it referred
to `numbers`, the closure will try to take ownership of the
vector. But the closure itself is created in a loop, and hence we will
actually create three closures, one for every iteration of the
loop. This means that all three of those closures would try to own
`numbers`, which is impossible -- `numbers` must have just one
owner. Rust detects this and gives us the error: we claim that
`numbers` has ownership, but our code tries to make three owners. This
may cause a safety problem, so Rust disallows it.
This is a little confusing because there are two closures here: the one passed
to `map`, and the one passed to `thread::scoped`. In this case, the closure for
`thread::scoped` is attempting to reference `numbers`, a `Vec<i32>`. This
closure is a `FnOnce` closure, as that’s what `thread::scoped` takes as an
argument. `FnOnce` closures take ownership of their environment. That’s fine,
but there’s one detail: because of `map`, we’re going to make three of these
closures. And since all three try to take ownership of `numbers`, that would be
a problem. That’s what it means by ‘cannot move out of captured outer
variable’: our `thread::scoped` closure wants to take ownership, and it can’t,
because the closure for `map` won’t let it.

What to do here? Rust has two types that helps us: `Arc<T>` and `Mutex<T>`.
*Arc* stands for "atomically reference counted". In other words, an Arc will
Expand Down
69 changes: 36 additions & 33 deletions src/doc/trpl/compound-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ This pattern is very powerful, and we'll see it repeated more later.

There are also a few things you can do with a tuple as a whole, without
destructuring. You can assign one tuple into another, if they have the same
contained types and arity. Tuples have the same arity when they have the same
contained types and [arity]. Tuples have the same arity when they have the same
length.

```rust
Expand Down Expand Up @@ -196,8 +196,9 @@ Now, we have actual names, rather than positions. Good names are important,
and with a struct, we have actual names.

There _is_ one case when a tuple struct is very useful, though, and that's a
tuple struct with only one element. We call this a *newtype*, because it lets
you create a new type that's similar to another one:
tuple struct with only one element. We call this the *newtype* pattern, because
it allows you to create a new type, distinct from that of its contained value
and expressing its own semantic meaning:

```{rust}
struct Inches(i32);
Expand All @@ -216,7 +217,7 @@ destructuring `let`, as we discussed previously in 'tuples.' In this case, the

Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
feature of Rust, and are used throughout the standard library. An `enum` is
a type which ties a set of alternates to a specific name. For example, below
a type which relates a set of alternates to a specific name. For example, below
we define `Character` to be either a `Digit` or something else. These
can be used via their fully scoped names: `Character::Other` (more about `::`
below).
Expand All @@ -228,8 +229,8 @@ enum Character {
}
```

An `enum` variant can be defined as most normal types. Below are some example
types which also would be allowed in an `enum`.
Most normal types are allowed as the variant components of an `enum`. Here are
some examples:

```rust
struct Empty;
Expand All @@ -239,15 +240,15 @@ struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
struct HeightDatabase(Vec<i32>);
```

So you see that depending on the sub-datastructure, the `enum` variant, same as
a struct, may or may not hold data. That is, in `Character`, `Digit` is a name
tied to an `i32` where `Other` is just a name. However, the fact that they are
distinct makes this very useful.
You see that, depending on its type, an `enum` variant may or may not hold data.
In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
value, where `Other` is only a name. However, the fact that they represent
distinct categories of `Character` is a very useful property.

As with structures, enums don't by default have access to operators such as
compare ( `==` and `!=`), binary operations (`*` and `+`), and order
(`<` and `>=`). As such, using the previous `Character` type, the
following code is invalid:
As with structures, the variants of an enum by default are not comparable with
equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
support other binary operations such as `*` and `+`. As such, the following code
is invalid for the example `Character` type:

```{rust,ignore}
// These assignments both succeed
Expand All @@ -265,9 +266,10 @@ let four_equals_ten = four == ten;
```

This may seem rather limiting, but it's a limitation which we can overcome.
There are two ways: by implementing equality ourselves, or by using the
[`match`][match] keyword. We don't know enough about Rust to implement equality
yet, but we can use the `Ordering` enum from the standard library, which does:
There are two ways: by implementing equality ourselves, or by pattern matching
variants with [`match`][match] expressions, which you'll learn in the next
chapter. We don't know enough about Rust to implement equality yet, but we can
use the `Ordering` enum from the standard library, which does:

```
enum Ordering {
Expand All @@ -277,9 +279,8 @@ enum Ordering {
}
```

Because we did not define `Ordering`, we must import it (from the std
library) with the `use` keyword. Here's an example of how `Ordering` is
used:
Because `Ordering` has already been defined for us, we will import it with the
`use` keyword. Here's an example of how it is used:

```{rust}
use std::cmp::Ordering;
Expand Down Expand Up @@ -313,17 +314,17 @@ the standard library if you need them.

Okay, let's talk about the actual code in the example. `cmp` is a function that
compares two things, and returns an `Ordering`. We return either
`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if
the two values are less, greater, or equal. Note that each variant of the
`enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not
`Greater`.
`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
whether the first value is less than, greater than, or equal to the second. Note
that each variant of the `enum` is namespaced under the `enum` itself: it's
`Ordering::Greater`, not `Greater`.

The `ordering` variable has the type `Ordering`, and so contains one of the
three values. We then do a bunch of `if`/`else` comparisons to check which
one it is.

This `Ordering::Greater` notation is too long. Let's use `use` to import the
`enum` variants instead. This will avoid full scoping:
This `Ordering::Greater` notation is too long. Let's use another form of `use`
to import the `enum` variants instead. This will avoid full scoping:

```{rust}
use std::cmp::Ordering::{self, Equal, Less, Greater};
Expand All @@ -347,16 +348,18 @@ fn main() {
```

Importing variants is convenient and compact, but can also cause name conflicts,
so do this with caution. It's considered good style to rarely import variants
for this reason.
so do this with caution. For this reason, it's normally considered better style
to `use` an enum rather than its variants directly.

As you can see, `enum`s are quite a powerful tool for data representation, and are
even more useful when they're [generic][generics] across types. Before we
get to generics, though, let's talk about how to use them with pattern matching, a
tool that will let us deconstruct this sum type (the type theory term for enums)
in a very elegant way and avoid all these messy `if`/`else`s.
As you can see, `enum`s are quite a powerful tool for data representation, and
are even more useful when they're [generic][generics] across types. Before we
get to generics, though, let's talk about how to use enums with pattern
matching, a tool that will let us deconstruct sum types (the type theory term
for enums) like `Ordering` in a very elegant way that avoids all these messy
and brittle `if`/`else`s.


[arity]: ./glossary.html#arity
[match]: ./match.html
[game]: ./guessing-game.html#comparing-guesses
[generics]: ./generics.html
11 changes: 5 additions & 6 deletions src/doc/trpl/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ us enforce that it can't leave the current thread.

### `Sync`

The second of these two trait is called [`Sync`](../std/marker/trait.Sync.html).
The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
When a type `T` implements `Sync`, it indicates to the compiler that something
of this type has no possibility of introducing memory unsafety when used from
multiple threads concurrently.

For example, sharing immutable data with an atomic reference count is
threadsafe. Rust provides a type like this, `Arc<T>`, and it implements `Sync`,
so that it could be safely shared between threads.
so it is safe to share between threads.

These two traits allow you to use the type system to make strong guarantees
about the properties of your code under concurrency. Before we demonstrate
Expand All @@ -69,7 +69,7 @@ fn main() {
}
```

The `Thread::scoped()` method accepts a closure, which is executed in a new
The `thread::scoped()` method accepts a closure, which is executed in a new
thread. It's called `scoped` because this thread returns a join guard:

```
Expand Down Expand Up @@ -208,10 +208,10 @@ Here's the error:

```text
<anon>:11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
<anon>:11 Thread::spawn(move || {
<anon>:11 thread::spawn(move || {
^~~~~~~~~~~~~
<anon>:11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
<anon>:11 Thread::spawn(move || {
<anon>:11 thread::spawn(move || {
^~~~~~~~~~~~~
```

Expand Down Expand Up @@ -322,7 +322,6 @@ While this channel is just sending a generic signal, we can send any data that
is `Send` over the channel!

```
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc;

Expand Down
2 changes: 1 addition & 1 deletion src/doc/trpl/crates-and-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ fn main() {
}
```

But it is not idiomatic. This is significantly more likely to introducing a
But it is not idiomatic. This is significantly more likely to introduce a
naming conflict. In our short program, it's not a big deal, but as it grows, it
becomes a problem. If we have conflicting names, Rust will give a compilation
error. For example, if we made the `japanese` functions public, and tried to do
Expand Down
35 changes: 35 additions & 0 deletions src/doc/trpl/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,41 @@ By repeating all parts of the example, you can ensure that your example still
compiles, while only showing the parts that are relevant to that part of your
explanation.

### Documenting macros

Here’s an example of documenting a macro:

```
/// Panic with a given message unless an expression evaluates to true.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(1 + 1 == 2, “Math is broken.”);
/// # }
/// ```
///
/// ```should_fail
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(true == false, “I’m broken.”);
/// # }
/// ```
#[macro_export]
macro_rules! panic_unless {
($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
}
```

You’ll note three things: we need to add our own `extern crate` line, so that
we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
`main()` as well. Finally, a judicious use of `#` to comment out those two
things, so they don’t show up in the output.

### Running documentation tests

To run the tests, either

```bash
Expand Down
33 changes: 31 additions & 2 deletions src/doc/trpl/more-strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Additionally, strings are not null-terminated and can contain null bytes.

Rust has two main types of strings: `&str` and `String`.

# &str
# `&str`

The first kind is a `&str`. This is pronounced a 'string slice'.
String literals are of the type `&str`:
Expand All @@ -36,7 +36,36 @@ Like vector slices, string slices are simply a pointer plus a length. This
means that they're a 'view' into an already-allocated string, such as a
string literal or a `String`.

# String
## `str`

You may occasionally see references to a `str` type, without the `&`. While
this type does exist, it’s not something you want to use yourself. Sometimes,
people confuse `str` for `String`, and write this:

```rust
struct S {
s: str,
}
```

This leads to ugly errors:

```text
error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
note: `str` does not have a constant size known at compile-time
```

Instead, this `struct` should be

```rust
struct S {
s: String,
}
```

So let’s talk about `String`s.

# `String`

A `String` is a heap-allocated string. This string is growable, and is
also guaranteed to be UTF-8. `String`s are commonly created by
Expand Down
9 changes: 3 additions & 6 deletions src/doc/trpl/pointers.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,10 @@ they go out of scope:
However, boxes do _not_ use reference counting or garbage collection. Boxes are
what's called an *affine type*. This means that the Rust compiler, at compile
time, determines when the box comes into and goes out of scope, and inserts the
appropriate calls there. Furthermore, boxes are a specific kind of affine type,
known as a *region*. You can read more about regions [in this paper on the
Cyclone programming
language](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf).
appropriate calls there.

You don't need to fully grok the theory of affine types or regions to grok
boxes, though. As a rough approximation, you can treat this Rust code:
You don't need to fully grok the theory of affine types to grok boxes, though.
As a rough approximation, you can treat this Rust code:

```{rust}
{
Expand Down
8 changes: 6 additions & 2 deletions src/doc/trpl/standard-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ doesn't work, so we're okay with that. In most cases, we would want to handle
the error case explicitly. `expect()` allows us to give an error message if
this crash happens.

We will cover the exact details of how all of this works later in the Guide.
For now, this gives you enough of a basic understanding to work with.
We will cover the exact details of how all of this works later in the Guide in
[Error Handling]. For now, this gives you enough of a basic understanding to
work with.

Back to the code we were working on! Here's a refresher:

Expand Down Expand Up @@ -157,3 +158,6 @@ here.

That's all you need to get basic input from the standard input! It's not too
complicated, but there are a number of small parts.


[Error Handling]: ./error-handling.html
3 changes: 3 additions & 0 deletions src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
///
/// On failure, return a null pointer and leave the original allocation intact.
///
/// If the allocation was relocated, the memory at the passed-in pointer is
/// undefined after the call.
///
/// Behavior is undefined if the requested size is 0 or the alignment is not a
/// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.
Expand Down
Loading