diff --git a/src/doc/index.md b/src/doc/index.md index 5a437e959b7fb..c4725c26e46bd 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -5,15 +5,14 @@ to jump to any particular section. # Getting Started -If you haven't seen Rust at all yet, the first thing you should read is the [30 -minute intro](intro.html). It will give you an overview of the basic ideas of Rust -at a high level. +If you haven't seen Rust at all yet, the first thing you should read is the +introduction to [The Rust Programming Language](book/index.html). It'll give +you a good idea of what Rust is like. -Once you know you really want to learn Rust, the next step is reading [The -Rust Programming Language](book/index.html). It is a lengthy explanation of -Rust, its syntax, and its concepts. Upon completing the book, you'll be an -intermediate Rust developer, and will have a good grasp of the fundamental -ideas behind Rust. +The book provides a lengthy explanation of Rust, its syntax, and its +concepts. Upon completing the book, you'll be an intermediate Rust +developer, and will have a good grasp of the fundamental ideas behind +Rust. [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 @@ -24,7 +23,7 @@ series of small examples. # Community & Getting Help 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 fastest way to get help. @@ -59,7 +58,7 @@ the language in as much detail as possible is in [the reference](reference.html) # 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. [Cargo](http://crates.io) is Rust's package manager, and its website contains @@ -69,16 +68,21 @@ lots of good documentation. # 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 FAQ](complement-lang-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) -# The standard library +# The Standard Library We have [API documentation for the entire standard 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 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). diff --git a/src/doc/reference.md b/src/doc/reference.md index 7501796227469..2ddec9ba424f2 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -426,12 +426,12 @@ x; x::y::z; ``` -Path components are usually [identifiers](#identifiers), but the trailing -component of a path may be an angle-bracket-enclosed list of type arguments. In -[expression](#expressions) context, the type argument list is given after a -final (`::`) namespace qualifier in order to disambiguate it from a relational -expression involving the less-than symbol (`<`). In type expression context, -the final namespace qualifier is omitted. +Path components are usually [identifiers](#identifiers), but they may +also include angle-bracket-enclosed lists of type arguments. In +[expression](#expressions) context, the type argument list is given +after a `::` namespace qualifier in order to disambiguate it from a +relational expression involving the less-than symbol (`<`). In type +expression context, the final namespace qualifier is omitted. 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: -* [Compiler plugins][plugin] can include arbitrary - Rust code that manipulates syntax trees at compile time. +* [Compiler plugins][plugin] can include arbitrary Rust code that + 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, declarative way. @@ -560,14 +561,18 @@ Nested repetitions are allowed. The parser used by the macro system is reasonably powerful, but the parsing of Rust syntax is restricted in two ways: -1. The parser will always parse as much as possible. If it attempts to match - `$i:expr [ , ]` against `8 [ , ]`, it will attempt to parse `i` as an array - index operation and fail. Adding a separator can solve this problem. +1. Macro definitions are required to include suitable separators after parsing + expressions and other bits of the Rust grammar. This implies that + 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 `$` _name_ `:` _designator_. This requirement most often affects name-designator pairs when they occur at the beginning of, or immediately after, a `$(...)*`; 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 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 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 -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 @@ -732,6 +738,7 @@ mod vec; mod thread { // Load the `local_data` module from `thread/local_data.rs` + // or `thread/local_data/mod.rs`. mod local_data; } ``` @@ -1004,7 +1011,8 @@ the guarantee that these issues are never caused by safe code. * `&mut` and `&` follow LLVM’s scoped [noalias] model, except if the `&T` contains an `UnsafeCell`. Unsafe code must not violate these aliasing guarantees. -* Mutating an immutable value/reference without `UnsafeCell` +* 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`. * Invoking undefined behavior via compiler intrinsics: * Indexing outside of the bounds of an object with `std::ptr::offset` (`offset` intrinsic), with @@ -1034,9 +1042,13 @@ be undesired. * Exiting without calling destructors * Sending signals * Accessing/modifying the file system -* Unsigned integer overflow (well-defined as wrapping) -* Signed integer overflow (well-defined as two’s complement representation - wrapping) +* Integer overflow + - Overflow is considered "unexpected" behavior and is always user-error, + 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 @@ -1310,11 +1322,26 @@ type of the value is not required to ascribe to `Sync`. ### 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: + +- functions +- constants +- 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. -Traits can include default implementations of methods, written in terms of some -unknown [`self` type](#self-types); the `self` type may either be completely -unspecified, or constrained by some other trait. +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 [implementations](#implementations). @@ -1359,15 +1386,18 @@ fn draw_twice(surface: Surface, sh: T) { } ``` -Traits also define an [trait object](#trait-objects) with the same name as the -trait. Values of this type are created by [casting](#type-cast-expressions) -pointer values (pointing to a type for which an implementation of the given -trait is in scope) to pointers to the trait name, used as a type. +Traits also define an [trait object](#trait-objects) with the same +name as the trait. Values of this type are created by coercing from a +pointer of some specific type to a pointer of trait type. For example, +`&T` could be coerced to `&Shape` if `T: Shape` holds (and similarly +for `Box`). This coercion can either be implicit or +[explicit](#type-cast-expressions). Here is an example of an explicit +coercion: ``` -# trait Shape { fn dummy(&self) { } } -# impl Shape for i32 { } -# let mycircle = 0i32; +trait Shape { } +impl Shape for i32 { } +let mycircle = 0i32; let myshape: Box = Box::new(mycircle) as Box; ``` @@ -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 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 @@ -2053,11 +2084,6 @@ The compiler automatically inlines functions based on internal heuristics. Incorrectly inlining functions can actually make the program slower, so it 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 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 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, which removes hidden flag added to a type that 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. The left operand of an [assignment](#assignment-expressions) or -[compound-assignment](#compound-assignment-expressions) expression is an lvalue -context, as is the single operand of a unary -[borrow](#unary-operator-expressions). All other expression contexts are -rvalue contexts. +[compound-assignment](#compound-assignment-expressions) expression is +an lvalue context, as is the single operand of a unary +[borrow](#unary-operator-expressions). The discriminant or subject of +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 location; when evaluated in an _rvalue context_, it denotes the value held _in_ that memory location. -When an rvalue is used in an lvalue context, a temporary un-named lvalue is -created and used instead. A temporary's lifetime equals the largest lifetime -of any reference that points to it. +##### Temporary lifetimes + +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 @@ -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, 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 -automatically dereferenced to make the field access possible. +Also, if the type of the expression to the left of the dot is a +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 @@ -2577,6 +2637,11 @@ let arr = ["a", "b"]; 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 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 -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. * `-` @@ -2613,11 +2678,20 @@ before the expression they apply to. implemented by the type and required for an outer expression that will or could mutate the dereference), and produces the result of dereferencing the `&` or `&mut` borrowed pointer returned from the overload method. - * `!` : Logical negation. On the boolean type, this flips between `true` and `false`. On integer types, this inverts the individual bits in the 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 @@ -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 An _assignment expression_ consists of an @@ -3348,6 +3429,22 @@ let bo: Binop = add; 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 A [lambda expression](#lambda-expressions) produces a closure value with @@ -3432,8 +3529,9 @@ has type `Vec`, a vector with element type `A`. ### Self types -The special type `self` has a meaning within methods inside an impl item. It -refers to the type of the implicit `self` argument. For example, in: +The special type `Self` has a meaning within traits and impls. In a trait definition, it refers +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 { @@ -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 method `make_string`. +The notation `&self` is a shorthand for `self: &Self`. In this case, +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 diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index de7ded76280f6..3f97928a56e3f 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -15,6 +15,7 @@ * [Concurrency](concurrency.md) * [Error Handling](error-handling.md) * [FFI](ffi.md) + * [Borrow and AsRef](borrow-and-asref.md) * [Syntax and Semantics](syntax-and-semantics.md) * [Variable Bindings](variable-bindings.md) * [Functions](functions.md) diff --git a/src/doc/trpl/borrow-and-asref.md b/src/doc/trpl/borrow-and-asref.md new file mode 100644 index 0000000000000..f5f314f1c21d6 --- /dev/null +++ b/src/doc/trpl/borrow-and-asref.md @@ -0,0 +1,93 @@ +% Borrow and AsRef + +The [`Borrow`][borrow] and [`AsRef`][asref] traits are very similar, but +different. Here’s 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 you’re 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(&self, k: &Q) -> Option<&V> + where K: Borrow, + 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 we’re interested +in here. It refers to a parameter of the `HashMap` itself: + +```rust,ignore +struct HashMap { +``` + +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`. That way, we can make a `HashMap` which uses `String` keys, +but use `&str`s when we’re 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 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 there’s 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 + 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. It’s used for converting some value to +a reference in generic code. Like this: + +```rust +let s = "Hello".to_string(); + +fn foo>(s: T) { + let slice = s.as_ref(); +} +``` + +# Which should I use? + +We can see how they’re kind of the same: they both deal with owned and borrowed +versions of some type. However, they’re a bit different. + +Choose `Borrow` when you want to abstract over different kinds of borrowing, or +when you’re 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 +you’re writing generic code. diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 86164a08a430f..25d5122b4e49e 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -5,7 +5,7 @@ Rust’s most unique and compelling features, with which Rust developers should become quite acquainted. Ownership is how Rust achieves its largest goal, 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’ * lifetimes, which you’re reading now diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 971bb7cd700db..b210f1c643f43 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -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 chapter: -* ownership, which you’re reading now. +* ownership, which you’re reading now * [borrowing][borrowing], and their associated feature ‘references’ * [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 ‘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 -of a zero cost abstraction. All of the analysis we’ll talk about in this guide +of a zero-cost abstraction. All of the analysis we’ll talk about in this guide is _done at compile time_. You do not pay any run-time cost for any of these features. @@ -41,7 +41,7 @@ With that in mind, let’s learn about 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 they’re bound to. This means that when a binding goes out of scope, the resource that they’re bound to are freed. For example: @@ -106,8 +106,8 @@ take(v); println!("v[0] is: {}", v[0]); ``` -Same error: “use of moved value.” When we transfer ownership to something else, -we say that we’ve ‘moved’ the thing we refer to. You don’t need some sort of +Same error: ‘use of moved value’. When we transfer ownership to something else, +we say that we’ve ‘moved’ the thing we refer to. You don’t need any sort of special annotation here, it’s the default thing that Rust does. ## The details @@ -121,19 +121,19 @@ let v = vec![1, 2, 3]; let v2 = v; ``` -The first line creates some data for the vector on the [stack][sh], `v`. The -vector’s data, however, is stored on the [heap][sh], and so it contains a -pointer to that data. When we move `v` to `v2`, it creates a copy of that pointer, -for `v2`. Which would mean two pointers to the contents of the vector on the -heap. That would be a problem: it would violate Rust’s safety guarantees by -introducing a data race. Therefore, Rust forbids using `v` after we’ve done the -move. +The first line allocates memory for the vector object, `v`, and for the data it +contains. The vector object is stored on the [stack][sh] and contains a pointer +to the content (`[1, 2, 3]`) stored on the [heap][sh]. When we move `v` to `v2`, +it creates a copy of that pointer, for `v2`. Which means that there would be two +pointers to the content of the vector on the heap. It would violate Rust’s +safety guarantees by introducing a data race. Therefore, Rust forbids using `v` +after we’ve done the move. [sh]: the-stack-and-the-heap.html It’s 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 -initially seems. +the bytes on the stack, depending on circumstances. So it may not be as +inefficient as it initially seems. ## `Copy` types diff --git a/src/doc/trpl/primitive-types.md b/src/doc/trpl/primitive-types.md index bb2bf028700d2..22483816769c3 100644 --- a/src/doc/trpl/primitive-types.md +++ b/src/doc/trpl/primitive-types.md @@ -15,7 +15,7 @@ let x = true; 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 diff --git a/src/doc/trpl/while-loops.md b/src/doc/trpl/while-loops.md index f2e2f6b6f49a7..e71d2033f49ed 100644 --- a/src/doc/trpl/while-loops.md +++ b/src/doc/trpl/while-loops.md @@ -1,4 +1,4 @@ -% while loops +% while Loops Rust also has a `while` loop. It looks like this: diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs index 7332bf4670ae5..a86a4b4215f23 100644 --- a/src/libcollections/borrow.rs +++ b/src/libcollections/borrow.rs @@ -37,6 +37,11 @@ use self::Cow::*; /// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given /// type can be borrowed as multiple different types. In particular, `Vec: /// Borrow>` and `Vec: 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")] pub trait Borrow { /// Immutably borrows from an owned value. diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index da6ac6bd752bf..f6987c1966493 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -24,6 +24,11 @@ use marker::Sized; /// 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 /// /// Both `String` and `&str` implement `AsRef`: diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 0f1e55544e1af..6690e6831afee 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -273,8 +273,8 @@ See also http://doc.rust-lang.org/book/unsafe.html E0137: r##" 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 -into a Rust program. +`#[main]` attribute. This is an error because there must be a unique entry +point into a Rust program. "##, E0152: r##" diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a896bd311698c..7e7af8006805d 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -10,8 +10,111 @@ #![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! { - E0154, E0157, E0153, 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 E0257, // inherent implementations are only allowed on types defined in the current module 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 E0365 // item is private } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index ea872d1014425..f9565d528e89a 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -186,7 +186,7 @@ struct Foo<'a> { ``` 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##" @@ -216,7 +216,7 @@ enum Foo<'a> { ``` 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##" diff --git a/src/test/compile-fail/issue-15919.rs b/src/test/compile-fail/issue-15919.rs new file mode 100644 index 0000000000000..1461cf2423888 --- /dev/null +++ b/src/test/compile-fail/issue-15919.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: the type `[i32; 9223372036854775808]` is too big for the current architecture + +fn main() { + let _x = [0; 9223372036854775808]; +}