1
Fork 0

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

- Successful merges: #24996, #25220, #25221, #25267, #25322, #25327, #25329, #25330, #25331, #25335
- Failed merges: #25334
This commit is contained in:
bors 2015-05-12 19:11:44 +00:00
commit c2b30b86df
16 changed files with 443 additions and 89 deletions

View file

@ -5,15 +5,14 @@ to jump to any particular section.
# Getting Started # Getting Started
If you haven't seen Rust at all yet, the first thing you should read is the [30 If you haven't seen Rust at all yet, the first thing you should read is the
minute intro](intro.html). It will give you an overview of the basic ideas of Rust introduction to [The Rust Programming Language](book/index.html). It'll give
at a high level. you a good idea of what Rust is like.
Once you know you really want to learn Rust, the next step is reading [The The book provides a lengthy explanation of Rust, its syntax, and its
Rust Programming Language](book/index.html). It is a lengthy explanation of concepts. Upon completing the book, you'll be an intermediate Rust
Rust, its syntax, and its concepts. Upon completing the book, you'll be an developer, and will have a good grasp of the fundamental ideas behind
intermediate Rust developer, and will have a good grasp of the fundamental Rust.
ideas behind Rust.
[Rust By Example][rbe] was originally a community resource, but was then [Rust By Example][rbe] was originally a community resource, but was then
donated to the Rust project. As the name implies, it teaches you Rust through a donated to the Rust project. As the name implies, it teaches you Rust through a
@ -24,7 +23,7 @@ series of small examples.
# Community & Getting Help # Community & Getting Help
If you need help with something, or just want to talk about Rust with others, If you need help with something, or just want to talk about Rust with others,
there's a few places you can do that: there are a few places you can do that:
The Rust IRC channels on [irc.mozilla.org](http://irc.mozilla.org/) are the The Rust IRC channels on [irc.mozilla.org](http://irc.mozilla.org/) are the
fastest way to get help. fastest way to get help.
@ -59,7 +58,7 @@ the language in as much detail as possible is in [the reference](reference.html)
# Tools # Tools
Rust's still a young language, so there isn't a ton of tooling yet, but the Rust is still a young language, so there isn't a ton of tooling yet, but the
tools we have are really nice. tools we have are really nice.
[Cargo](http://crates.io) is Rust's package manager, and its website contains [Cargo](http://crates.io) is Rust's package manager, and its website contains
@ -69,16 +68,21 @@ lots of good documentation.
# FAQs # FAQs
There are questions that are asked quite often, and so we've made FAQs for them: There are questions that are asked quite often, so we've made FAQs for them:
* [Language Design FAQ](complement-design-faq.html) * [Language Design FAQ](complement-design-faq.html)
* [Language FAQ](complement-lang-faq.html) * [Language FAQ](complement-lang-faq.html)
* [Project FAQ](complement-project-faq.html) * [Project FAQ](complement-project-faq.html)
* [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports) * [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports)
# The standard library # The Standard Library
We have [API documentation for the entire standard We have [API documentation for the entire standard
library](std/index.html). There's a list of crates on the left with more library](std/index.html). There's a list of crates on the left with more
specific sections, or you can use the search bar at the top to search for specific sections, or you can use the search bar at the top to search for
something if you know its name. something if you know its name.
# The Error Index
If you encounter an error while compiling your code you may be able to look it
up in the [Rust Compiler Error Index](error-index.html).

View file

@ -426,12 +426,12 @@ x;
x::y::z; x::y::z;
``` ```
Path components are usually [identifiers](#identifiers), but the trailing Path components are usually [identifiers](#identifiers), but they may
component of a path may be an angle-bracket-enclosed list of type arguments. In also include angle-bracket-enclosed lists of type arguments. In
[expression](#expressions) context, the type argument list is given after a [expression](#expressions) context, the type argument list is given
final (`::`) namespace qualifier in order to disambiguate it from a relational after a `::` namespace qualifier in order to disambiguate it from a
expression involving the less-than symbol (`<`). In type expression context, relational expression involving the less-than symbol (`<`). In type
the final namespace qualifier is omitted. expression context, the final namespace qualifier is omitted.
Two examples of paths with type arguments: Two examples of paths with type arguments:
@ -497,8 +497,9 @@ names, and invoked through a consistent syntax: `some_extension!(...)`.
Users of `rustc` can define new syntax extensions in two ways: Users of `rustc` can define new syntax extensions in two ways:
* [Compiler plugins][plugin] can include arbitrary * [Compiler plugins][plugin] can include arbitrary Rust code that
Rust code that manipulates syntax trees at compile time. manipulates syntax trees at compile time. Note that the interface
for compiler plugins is considered highly unstable.
* [Macros](book/macros.html) define new syntax in a higher-level, * [Macros](book/macros.html) define new syntax in a higher-level,
declarative way. declarative way.
@ -560,14 +561,18 @@ Nested repetitions are allowed.
The parser used by the macro system is reasonably powerful, but the parsing of The parser used by the macro system is reasonably powerful, but the parsing of
Rust syntax is restricted in two ways: Rust syntax is restricted in two ways:
1. The parser will always parse as much as possible. If it attempts to match 1. Macro definitions are required to include suitable separators after parsing
`$i:expr [ , ]` against `8 [ , ]`, it will attempt to parse `i` as an array expressions and other bits of the Rust grammar. This implies that
index operation and fail. Adding a separator can solve this problem. a macro definition like `$i:expr [ , ]` is not legal, because `[` could be part
of an expression. A macro definition like `$i:expr,` or `$i:expr;` would be legal,
however, because `,` and `;` are legal separators. See [RFC 550] for more information.
2. The parser must have eliminated all ambiguity by the time it reaches a `$` 2. The parser must have eliminated all ambiguity by the time it reaches a `$`
_name_ `:` _designator_. This requirement most often affects name-designator _name_ `:` _designator_. This requirement most often affects name-designator
pairs when they occur at the beginning of, or immediately after, a `$(...)*`; pairs when they occur at the beginning of, or immediately after, a `$(...)*`;
requiring a distinctive token in front can solve the problem. requiring a distinctive token in front can solve the problem.
[RFC 550]: https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md
# Crates and source files # Crates and source files
Although Rust, like any other language, can be implemented by an interpreter as Although Rust, like any other language, can be implemented by an interpreter as
@ -686,7 +691,8 @@ type arguments as a list of comma-separated types enclosed within angle
brackets, in order to refer to the type-parameterized item. In practice, the brackets, in order to refer to the type-parameterized item. In practice, the
type-inference system can usually infer such argument types from context. There type-inference system can usually infer such argument types from context. There
are no general type-parametric types, only type-parametric items. That is, Rust are no general type-parametric types, only type-parametric items. That is, Rust
has no notion of type abstraction: there are no first-class "forall" types. has no notion of type abstraction: there are no higher-ranked (or "forall") types
abstracted over other types, though higher-ranked types do exist for lifetimes.
### Modules ### Modules
@ -732,6 +738,7 @@ mod vec;
mod thread { mod thread {
// Load the `local_data` module from `thread/local_data.rs` // Load the `local_data` module from `thread/local_data.rs`
// or `thread/local_data/mod.rs`.
mod local_data; mod local_data;
} }
``` ```
@ -1004,7 +1011,8 @@ the guarantee that these issues are never caused by safe code.
* `&mut` and `&` follow LLVMs scoped [noalias] model, except if the `&T` * `&mut` and `&` follow LLVMs scoped [noalias] model, except if the `&T`
contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
guarantees. guarantees.
* Mutating an immutable value/reference without `UnsafeCell<U>` * Mutating non-mutable data (that is, data reached through a shared reference or
data owned by a `let` binding), unless that data is contained within an `UnsafeCell<U>`.
* Invoking undefined behavior via compiler intrinsics: * Invoking undefined behavior via compiler intrinsics:
* Indexing outside of the bounds of an object with `std::ptr::offset` * Indexing outside of the bounds of an object with `std::ptr::offset`
(`offset` intrinsic), with (`offset` intrinsic), with
@ -1034,9 +1042,13 @@ be undesired.
* Exiting without calling destructors * Exiting without calling destructors
* Sending signals * Sending signals
* Accessing/modifying the file system * Accessing/modifying the file system
* Unsigned integer overflow (well-defined as wrapping) * Integer overflow
* Signed integer overflow (well-defined as twos complement representation - Overflow is considered "unexpected" behavior and is always user-error,
wrapping) unless the `wrapping` primitives are used. In non-optimized builds, the compiler
will insert debug checks that panic on overflow, but in optimized builds overflow
instead results in wrapped values. See [RFC 560] for the rationale and more details.
[RFC 560]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md
#### Diverging functions #### Diverging functions
@ -1310,11 +1322,26 @@ type of the value is not required to ascribe to `Sync`.
### Traits ### Traits
A _trait_ describes a set of method types. A _trait_ describes an abstract interface that types can
implement. This interface consists of associated items, which come in
three varieties:
Traits can include default implementations of methods, written in terms of some - functions
unknown [`self` type](#self-types); the `self` type may either be completely - constants
unspecified, or constrained by some other trait. - types
Associated functions whose first parameter is named `self` are called
methods and may be invoked using `.` notation (e.g., `x.foo()`).
All traits define an implicit type parameter `Self` that refers to
"the type that is implementing this interface". Traits may also
contain additional type parameters. These type parameters (including
`Self`) may be constrained by other traits and so forth as usual.
Trait bounds on `Self` are considered "supertraits". These are
required to be acyclic. Supertraits are somewhat different from other
constraints in that they affect what methods are available in the
vtable when the trait is used as a [trait object](#trait-objects).
Traits are implemented for specific types through separate Traits are implemented for specific types through separate
[implementations](#implementations). [implementations](#implementations).
@ -1359,15 +1386,18 @@ fn draw_twice<T: Shape>(surface: Surface, sh: T) {
} }
``` ```
Traits also define an [trait object](#trait-objects) with the same name as the Traits also define an [trait object](#trait-objects) with the same
trait. Values of this type are created by [casting](#type-cast-expressions) name as the trait. Values of this type are created by coercing from a
pointer values (pointing to a type for which an implementation of the given pointer of some specific type to a pointer of trait type. For example,
trait is in scope) to pointers to the trait name, used as a type. `&T` could be coerced to `&Shape` if `T: Shape` holds (and similarly
for `Box<T>`). This coercion can either be implicit or
[explicit](#type-cast-expressions). Here is an example of an explicit
coercion:
``` ```
# trait Shape { fn dummy(&self) { } } trait Shape { }
# impl Shape for i32 { } impl Shape for i32 { }
# let mycircle = 0i32; let mycircle = 0i32;
let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>; let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
``` ```
@ -2041,7 +2071,8 @@ The name `str_eq` has a special meaning to the Rust compiler, and the presence
of this definition means that it will use this definition when generating calls of this definition means that it will use this definition when generating calls
to the string equality function. to the string equality function.
A complete list of the built-in language items will be added in the future. The set of language items is currently considered unstable. A complete
list of the built-in language items will be added in the future.
### Inline attributes ### Inline attributes
@ -2053,11 +2084,6 @@ The compiler automatically inlines functions based on internal heuristics.
Incorrectly inlining functions can actually make the program slower, so it Incorrectly inlining functions can actually make the program slower, so it
should be used with care. should be used with care.
Immutable statics are always considered inlineable unless marked with
`#[inline(never)]`. It is undefined whether two different inlineable statics
have the same memory address. In other words, the compiler is free to collapse
duplicate inlineable statics together.
`#[inline]` and `#[inline(always)]` always cause the function to be serialized `#[inline]` and `#[inline(always)]` always cause the function to be serialized
into the crate metadata to allow cross-crate inlining. into the crate metadata to allow cross-crate inlining.
@ -2259,10 +2285,6 @@ The currently implemented features of the reference compiler are:
* `unboxed_closures` - Rust's new closure design, which is currently a work in * `unboxed_closures` - Rust's new closure design, which is currently a work in
progress feature with many known bugs. progress feature with many known bugs.
* `unsafe_destructor` - Allows use of the `#[unsafe_destructor]` attribute,
which is considered wildly unsafe and will be
obsoleted by language improvements.
* `unsafe_no_drop_flag` - Allows use of the `#[unsafe_no_drop_flag]` attribute, * `unsafe_no_drop_flag` - Allows use of the `#[unsafe_no_drop_flag]` attribute,
which removes hidden flag added to a type that which removes hidden flag added to a type that
implements the `Drop` trait. The design for the implements the `Drop` trait. The design for the
@ -2382,18 +2404,54 @@ expressions](#index-expressions) (`expr[expr]`), and [field
references](#field-expressions) (`expr.f`). All other expressions are rvalues. references](#field-expressions) (`expr.f`). All other expressions are rvalues.
The left operand of an [assignment](#assignment-expressions) or The left operand of an [assignment](#assignment-expressions) or
[compound-assignment](#compound-assignment-expressions) expression is an lvalue [compound-assignment](#compound-assignment-expressions) expression is
context, as is the single operand of a unary an lvalue context, as is the single operand of a unary
[borrow](#unary-operator-expressions). All other expression contexts are [borrow](#unary-operator-expressions). The discriminant or subject of
rvalue contexts. a [match expression](#match-expressions) may be an lvalue context, if
ref bindings are made, but is otherwise an rvalue context. All other
expression contexts are rvalue contexts.
When an lvalue is evaluated in an _lvalue context_, it denotes a memory When an lvalue is evaluated in an _lvalue context_, it denotes a memory
location; when evaluated in an _rvalue context_, it denotes the value held _in_ location; when evaluated in an _rvalue context_, it denotes the value held _in_
that memory location. that memory location.
When an rvalue is used in an lvalue context, a temporary un-named lvalue is ##### Temporary lifetimes
created and used instead. A temporary's lifetime equals the largest lifetime
of any reference that points to it. When an rvalue is used in an lvalue context, a temporary un-named
lvalue is created and used instead. The lifetime of temporary values
is typically the innermost enclosing statement; the tail expression of
a block is considered part of the statement that encloses the block.
When a temporary rvalue is being created that is assigned into a `let`
declaration, however, the temporary is created with the lifetime of
the enclosing block instead, as using the enclosing statement (the
`let` declaration) would be a guaranteed error (since a pointer to the
temporary would be stored into a variable, but the temporary would be
freed before the variable could be used). The compiler uses simple
syntactic rules to decide which values are being assigned into a `let`
binding, and therefore deserve a longer temporary lifetime.
Here are some examples:
- `let x = foo(&temp())`. The expression `temp()` is an rvalue. As it
is being borrowed, a temporary is created which will be freed after
the innermost enclosing statement (the `let` declaration, in this case).
- `let x = temp().foo()`. This is the same as the previous example,
except that the value of `temp()` is being borrowed via autoref on a
method-call. Here we are assuming that `foo()` is an `&self` method
defined in some trait, say `Foo`. In other words, the expression
`temp().foo()` is equivalent to `Foo::foo(&temp())`.
- `let x = &temp()`. Here, the same temporary is being assigned into
`x`, rather than being passed as a parameter, and hence the
temporary's lifetime is considered to be the enclosing block.
- `let x = SomeStruct { foo: &temp() }`. As in the previous case, the
temporary is assigned into a struct which is then assigned into a
binding, and hence it is given the lifetime of the enclosing block.
- `let x = [ &temp() ]`. As in the previous case, the
temporary is assigned into an array which is then assigned into a
binding, and hence it is given the lifetime of the enclosing block.
- `let ref x = temp()`. In this case, the temporary is created using a ref binding,
but the result is the same: the lifetime is extended to the enclosing block.
#### Moved and copied types #### Moved and copied types
@ -2535,8 +2593,10 @@ A field access is an [lvalue](#lvalues,-rvalues-and-temporaries) referring to
the value of that field. When the type providing the field inherits mutability, the value of that field. When the type providing the field inherits mutability,
it can be [assigned](#assignment-expressions) to. it can be [assigned](#assignment-expressions) to.
Also, if the type of the expression to the left of the dot is a pointer, it is Also, if the type of the expression to the left of the dot is a
automatically dereferenced to make the field access possible. pointer, it is automatically dereferenced as many times as necessary
to make the field access possible. In cases of ambiguity, we prefer
fewer autoderefs to more.
### Array expressions ### Array expressions
@ -2577,6 +2637,11 @@ let arr = ["a", "b"];
arr[10]; // panics arr[10]; // panics
``` ```
Also, if the type of the expression to the left of the brackets is a
pointer, it is automatically dereferenced as many times as necessary
to make the indexing possible. In cases of ambiguity, we prefer fewer
autoderefs to more.
### Range expressions ### Range expressions
The `..` operator will construct an object of one of the `std::ops::Range` variants. The `..` operator will construct an object of one of the `std::ops::Range` variants.
@ -2599,7 +2664,7 @@ assert_eq!(x,y);
### Unary operator expressions ### Unary operator expressions
Rust defines three unary operators. They are all written as prefix operators, Rust defines the following unary operators. They are all written as prefix operators,
before the expression they apply to. before the expression they apply to.
* `-` * `-`
@ -2613,11 +2678,20 @@ before the expression they apply to.
implemented by the type and required for an outer expression that will or implemented by the type and required for an outer expression that will or
could mutate the dereference), and produces the result of dereferencing the could mutate the dereference), and produces the result of dereferencing the
`&` or `&mut` borrowed pointer returned from the overload method. `&` or `&mut` borrowed pointer returned from the overload method.
* `!` * `!`
: Logical negation. On the boolean type, this flips between `true` and : Logical negation. On the boolean type, this flips between `true` and
`false`. On integer types, this inverts the individual bits in the `false`. On integer types, this inverts the individual bits in the
two's complement representation of the value. two's complement representation of the value.
* `&` and `&mut`
: Borrowing. When applied to an lvalue, these operators produce a
reference (pointer) to the lvalue. The lvalue is also placed into
a borrowed state for the duration of the reference. For a shared
borrow (`&`), this implies that the lvalue may not be mutated, but
it may be read or shared again. For a mutable borrow (`&mut`), the
lvalue may not be accessed in any way until the borrow expires.
If the `&` or `&mut` operators are applied to an rvalue, a
temporary value is created; the lifetime of this temporary value
is defined by [syntactic rules](#temporary-lifetimes).
### Binary operator expressions ### Binary operator expressions
@ -2727,6 +2801,13 @@ fn avg(v: &[f64]) -> f64 {
} }
``` ```
Some of the conversions which can be done through the `as` operator
can also be done implicitly at various points in the program, such as
argument passing and assignment to a `let` binding with an explicit
type. Implicit conversions are limited to "harmless" conversions that
do not lose information and which have minimal or no risk of
surprising side-effects on the dynamic execution semantics.
#### Assignment expressions #### Assignment expressions
An _assignment expression_ consists of an An _assignment expression_ consists of an
@ -3348,6 +3429,22 @@ let bo: Binop = add;
x = bo(5,7); x = bo(5,7);
``` ```
#### Function types for specific items
Internally to the compiler, there are also function types that are specific to a particular
function item. In the following snippet, for example, the internal types of the functions
`foo` and `bar` are different, despite the fact that they have the same signature:
```
fn foo() { }
fn bar() { }
```
The types of `foo` and `bar` can both be implicitly coerced to the fn
pointer type `fn()`. There is currently no syntax for unique fn types,
though the compiler will emit a type like `fn() {foo}` in error
messages to indicate "the unique fn type for the function `foo`".
### Closure types ### Closure types
A [lambda expression](#lambda-expressions) produces a closure value with A [lambda expression](#lambda-expressions) produces a closure value with
@ -3432,8 +3529,9 @@ has type `Vec<A>`, a vector with element type `A`.
### Self types ### Self types
The special type `self` has a meaning within methods inside an impl item. It The special type `Self` has a meaning within traits and impls. In a trait definition, it refers
refers to the type of the implicit `self` argument. For example, in: to an implicit type parameter representing the "implementing" type. In an impl,
it is an alias for the implementing type. For example, in:
``` ```
trait Printable { trait Printable {
@ -3447,8 +3545,9 @@ impl Printable for String {
} }
``` ```
`self` refers to the value of type `String` that is the receiver for a call to The notation `&self` is a shorthand for `self: &Self`. In this case,
the method `make_string`. in the impl, `Self` refers to the value of type `String` that is the
receiver for a call to the method `make_string`.
# Special traits # Special traits

View file

@ -15,6 +15,7 @@
* [Concurrency](concurrency.md) * [Concurrency](concurrency.md)
* [Error Handling](error-handling.md) * [Error Handling](error-handling.md)
* [FFI](ffi.md) * [FFI](ffi.md)
* [Borrow and AsRef](borrow-and-asref.md)
* [Syntax and Semantics](syntax-and-semantics.md) * [Syntax and Semantics](syntax-and-semantics.md)
* [Variable Bindings](variable-bindings.md) * [Variable Bindings](variable-bindings.md)
* [Functions](functions.md) * [Functions](functions.md)

View file

@ -0,0 +1,93 @@
% Borrow and AsRef
The [`Borrow`][borrow] and [`AsRef`][asref] traits are very similar, but
different. Heres a quick refresher on what these two traits mean.
[borrow]: ../std/borrow/trait.Borrow.html
[asref]: ../std/convert/trait.AsRef.html
# Borrow
The `Borrow` trait is used when youre writing a datastructure, and you want to
use either an owned or borrowed type as synonymous for some purpose.
For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`:
```rust,ignore
fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where K: Borrow<Q>,
Q: Hash + Eq
```
[hashmap]: ../std/collections/struct.HashMap.html
[get]: ../std/collections/struct.HashMap.html#method.get
This signature is pretty complicated. The `K` parameter is what were interested
in here. It refers to a parameter of the `HashMap` itself:
```rust,ignore
struct HashMap<K, V, S = RandomState> {
```
The `K` parameter is the type of _key_ the `HashMap` uses. So, looking at
the signature of `get()` again, we can use `get()` when the key implements
`Borrow<Q>`. That way, we can make a `HashMap` which uses `String` keys,
but use `&str`s when were searching:
```rust
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("Foo".to_string(), 42);
assert_eq!(map.get("Foo"), Some(&42));
```
This is because the standard library has `impl Borrow<str> for String`.
For most types, when you want to take an owned or borrowed type, a `&T` is
enough. But one area where `Borrow` is effective is when theres more than one
kind of borrowed value. Slices are an area where this is especially true: you
can have both an `&[T]` or a `&mut [T]`. If we wanted to accept both of these
types, `Borrow` is up for it:
```
use std::borrow::Borrow;
use std::fmt::Display;
fn foo<T: Borrow<i32> + Display>(a: T) {
println!("a is borrowed: {}", a);
}
let mut i = 5;
foo(&i);
foo(&mut i);
```
This will print out `a is borrowed: 5` twice.
# AsRef
The `AsRef` trait is a conversion trait. Its used for converting some value to
a reference in generic code. Like this:
```rust
let s = "Hello".to_string();
fn foo<T: AsRef<str>>(s: T) {
let slice = s.as_ref();
}
```
# Which should I use?
We can see how theyre kind of the same: they both deal with owned and borrowed
versions of some type. However, theyre a bit different.
Choose `Borrow` when you want to abstract over different kinds of borrowing, or
when youre building a datastructure that treats owned and borrowed values in
equivalent ways, such as hashing and comparison.
Choose `AsRef` when you want to convert something to a reference directly, and
youre writing generic code.

View file

@ -5,7 +5,7 @@ Rusts most unique and compelling features, with which Rust developers should
become quite acquainted. Ownership is how Rust achieves its largest goal, become quite acquainted. Ownership is how Rust achieves its largest goal,
memory safety. There are a few distinct concepts, each with its own chapter: memory safety. There are a few distinct concepts, each with its own chapter:
* [ownership][ownership], ownership, the key concept * [ownership][ownership], the key concept
* [borrowing][borrowing], and their associated feature references * [borrowing][borrowing], and their associated feature references
* lifetimes, which youre reading now * lifetimes, which youre reading now

View file

@ -6,7 +6,7 @@ become quite acquainted. Ownership is how Rust achieves its largest goal,
memory safety. There are a few distinct concepts, each with its own memory safety. There are a few distinct concepts, each with its own
chapter: chapter:
* ownership, which youre reading now. * ownership, which youre reading now
* [borrowing][borrowing], and their associated feature references * [borrowing][borrowing], and their associated feature references
* [lifetimes][lifetimes], an advanced concept of borrowing * [lifetimes][lifetimes], an advanced concept of borrowing
@ -23,7 +23,7 @@ Before we get to the details, two important notes about the ownership system.
Rust has a focus on safety and speed. It accomplishes these goals through many Rust has a focus on safety and speed. It accomplishes these goals through many
zero-cost abstractions, which means that in Rust, abstractions cost as little zero-cost abstractions, which means that in Rust, abstractions cost as little
as possible in order to make them work. The ownership system is a prime example as possible in order to make them work. The ownership system is a prime example
of a zero cost abstraction. All of the analysis well talk about in this guide of a zero-cost abstraction. All of the analysis well talk about in this guide
is _done at compile time_. You do not pay any run-time cost for any of these is _done at compile time_. You do not pay any run-time cost for any of these
features. features.
@ -41,7 +41,7 @@ With that in mind, lets learn about ownership.
# Ownership # Ownership
[`Variable bindings`][bindings] have a property in Rust: they have ownership [Variable bindings][bindings] have a property in Rust: they have ownership
of what theyre bound to. This means that when a binding goes out of scope, the of what theyre bound to. This means that when a binding goes out of scope, the
resource that theyre bound to are freed. For example: resource that theyre bound to are freed. For example:
@ -106,8 +106,8 @@ take(v);
println!("v[0] is: {}", v[0]); println!("v[0] is: {}", v[0]);
``` ```
Same error: “use of moved value.” When we transfer ownership to something else, Same error: use of moved value. When we transfer ownership to something else,
we say that weve moved the thing we refer to. You dont need some sort of we say that weve moved the thing we refer to. You dont need any sort of
special annotation here, its the default thing that Rust does. special annotation here, its the default thing that Rust does.
## The details ## The details
@ -121,19 +121,19 @@ let v = vec![1, 2, 3];
let v2 = v; let v2 = v;
``` ```
The first line creates some data for the vector on the [stack][sh], `v`. The The first line allocates memory for the vector object, `v`, and for the data it
vectors data, however, is stored on the [heap][sh], and so it contains a contains. The vector object is stored on the [stack][sh] and contains a pointer
pointer to that data. When we move `v` to `v2`, it creates a copy of that pointer, to the content (`[1, 2, 3]`) stored on the [heap][sh]. When we move `v` to `v2`,
for `v2`. Which would mean two pointers to the contents of the vector on the it creates a copy of that pointer, for `v2`. Which means that there would be two
heap. That would be a problem: it would violate Rusts safety guarantees by pointers to the content of the vector on the heap. It would violate Rusts
introducing a data race. Therefore, Rust forbids using `v` after weve done the safety guarantees by introducing a data race. Therefore, Rust forbids using `v`
move. after weve done the move.
[sh]: the-stack-and-the-heap.html [sh]: the-stack-and-the-heap.html
Its also important to note that optimizations may remove the actual copy of Its also important to note that optimizations may remove the actual copy of
the bytes, depending on circumstances. So it may not be as inefficient as it the bytes on the stack, depending on circumstances. So it may not be as
initially seems. inefficient as it initially seems.
## `Copy` types ## `Copy` types

View file

@ -15,7 +15,7 @@ let x = true;
let y: bool = false; let y: bool = false;
``` ```
A common use of booleans is in [`if` statements][if]. A common use of booleans is in [`if` conditionals][if].
[if]: if.html [if]: if.html

View file

@ -1,4 +1,4 @@
% while loops % while Loops
Rust also has a `while` loop. It looks like this: Rust also has a `while` loop. It looks like this:

View file

@ -37,6 +37,11 @@ use self::Cow::*;
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given /// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>: /// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`. /// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
///
/// `Borrow` is very similar to, but different than, `AsRef`. See
/// [the book][book] for more.
///
/// [book]: ../../book/borrow-and-asref.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> { pub trait Borrow<Borrowed: ?Sized> {
/// Immutably borrows from an owned value. /// Immutably borrows from an owned value.

View file

@ -24,6 +24,11 @@ use marker::Sized;
/// A cheap, reference-to-reference conversion. /// A cheap, reference-to-reference conversion.
/// ///
/// `AsRef` is very similar to, but different than, `Borrow`. See
/// [the book][book] for more.
///
/// [book]: ../../book/borrow-and-asref.html
///
/// # Examples /// # Examples
/// ///
/// Both `String` and `&str` implement `AsRef<str>`: /// Both `String` and `&str` implement `AsRef<str>`:

View file

@ -5722,6 +5722,9 @@ pub mod funcs {
pub fn tcgetpgrp(fd: c_int) -> pid_t; pub fn tcgetpgrp(fd: c_int) -> pid_t;
pub fn ttyname(fd: c_int) -> *mut c_char; pub fn ttyname(fd: c_int) -> *mut c_char;
pub fn unlink(c: *const c_char) -> c_int; pub fn unlink(c: *const c_char) -> c_int;
pub fn wait(status: *const c_int) -> pid_t;
pub fn waitpid(pid: pid_t, status: *const c_int, options: c_int)
-> pid_t;
pub fn write(fd: c_int, buf: *const c_void, count: size_t) pub fn write(fd: c_int, buf: *const c_void, count: size_t)
-> ssize_t; -> ssize_t;
pub fn pread(fd: c_int, buf: *mut c_void, count: size_t, pub fn pread(fd: c_int, buf: *mut c_void, count: size_t,
@ -5773,6 +5776,9 @@ pub mod funcs {
pub fn sysconf(name: c_int) -> c_long; pub fn sysconf(name: c_int) -> c_long;
pub fn ttyname(fd: c_int) -> *mut c_char; pub fn ttyname(fd: c_int) -> *mut c_char;
pub fn unlink(c: *const c_char) -> c_int; pub fn unlink(c: *const c_char) -> c_int;
pub fn wait(status: *const c_int) -> pid_t;
pub fn waitpid(pid: pid_t, status: *const c_int, options: c_int)
-> pid_t;
pub fn write(fd: c_int, buf: *const c_void, count: size_t) pub fn write(fd: c_int, buf: *const c_void, count: size_t)
-> ssize_t; -> ssize_t;
pub fn pread(fd: c_int, buf: *mut c_void, count: size_t, pub fn pread(fd: c_int, buf: *mut c_void, count: size_t,

View file

@ -273,8 +273,8 @@ See also http://doc.rust-lang.org/book/unsafe.html
E0137: r##" E0137: r##"
This error indicates that the compiler found multiple functions with the This error indicates that the compiler found multiple functions with the
#[main] attribute. This is an error because there must be a unique entry point `#[main]` attribute. This is an error because there must be a unique entry
into a Rust program. point into a Rust program.
"##, "##,
E0152: r##" E0152: r##"

View file

@ -10,8 +10,111 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {
E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.
Here is an example that demonstrates the error:
```
fn f() {
// Variable declaration before import
let x = 0;
use std::io::Read;
...
}
```
The solution is to declare the imports at the top of the block, function, or
file.
Here is the previous example again, with the correct order:
```
fn f() {
use std::io::Read;
let x = 0;
...
}
```
See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:
http://doc.rust-lang.org/reference.html#statements
"##,
E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.
Wrong example:
```
extern crate a;
extern crate crate_a as a;
```
The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.
Correct example:
```
extern crate a;
extern crate crate_a as other_name;
```
"##,
E0260: r##"
The name for an item declaration conflicts with an external crate's name.
For instance,
```
extern crate abc;
struct abc;
```
There are two possible solutions:
Solution #1: Rename the item.
```
extern crate abc;
struct xyz;
```
Solution #2: Import the crate with a different name.
```
extern crate abc as xyz;
struct abc;
```
See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:
http://doc.rust-lang.org/reference.html#statements
"##,
E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.
See the Types section of the reference for more information about the primitive
types:
http://doc.rust-lang.org/reference.html#types
"##
}
register_diagnostics! { register_diagnostics! {
E0154,
E0157, E0157,
E0153, E0153,
E0251, // a named type or value has already been imported in this module E0251, // a named type or value has already been imported in this module
@ -22,9 +125,6 @@ register_diagnostics! {
E0256, // import conflicts with type in this module E0256, // import conflicts with type in this module
E0257, // inherent implementations are only allowed on types defined in the current module E0257, // inherent implementations are only allowed on types defined in the current module
E0258, // import conflicts with existing submodule E0258, // import conflicts with existing submodule
E0259, // an extern crate has already been imported into this module
E0260, // name conflicts with an external crate that has been imported into this module
E0317, // user-defined types or type parameters cannot shadow the primitive types
E0364, // item is private E0364, // item is private
E0365 // item is private E0365 // item is private
} }

View file

@ -186,7 +186,7 @@ struct Foo<'a> {
``` ```
This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
differs from the behavior for `&T`, which is `Copy` when `T` is `Copy`). differs from the behavior for `&T`, which is always `Copy`).
"##, "##,
E0205: r##" E0205: r##"
@ -216,7 +216,7 @@ enum Foo<'a> {
``` ```
This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
differs from the behavior for `&T`, which is `Copy` when `T` is `Copy`). differs from the behavior for `&T`, which is always `Copy`).
"##, "##,
E0206: r##" E0206: r##"

View file

@ -0,0 +1,25 @@
// 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.
trait Foo {
fn answer(self);
}
struct NoData<T>;
//~^ ERROR: parameter `T` is never used
impl<T> Foo for T where NoData<T>: Foo {
//~^ ERROR: overflow evaluating the requirement
fn answer(self) {
let val: NoData<T> = NoData;
}
}
fn main() {}

View file

@ -0,0 +1,16 @@
// 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.
// exec-env:RUST_LOG=rustc::middle=debug
fn main() {
let b = 1isize;
println!("{}", b);
}