diff --git a/RELEASES.md b/RELEASES.md index 5ff06f2f810..a247eb2e955 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -94,11 +94,11 @@ Misc the `-Z unstable-options` flag. * [When running tests with `--test`, rustdoc will pass `--cfg` arguments to the compiler][1.7dt]. -* [The compiler is built with RPATH information by default][1.7rp]. +* [The compiler is built with RPATH information by default][1.7rpa]. This means that it will be possible to run `rustc` when installed in unusual configurations without configuring the dynamic linker search path explicitly. -* [`rustc` passes `--enable-new-dtags` to GNU ld][1.7dt]. This makes +* [`rustc` passes `--enable-new-dtags` to GNU ld][1.7dta]. This makes any RPATH entries (emitted with `-C rpath`) *not* take precedence over `LD_LIBRARY_PATH`. @@ -132,7 +132,7 @@ Compatibility Notes [1.7cp]: https://github.com/rust-lang/cargo/pull/2224 [1.7d]: https://github.com/rust-lang/rust/pull/30724 [1.7dt]: https://github.com/rust-lang/rust/pull/30372 -[1.7dt]: https://github.com/rust-lang/rust/pull/30394 +[1.7dta]: https://github.com/rust-lang/rust/pull/30394 [1.7f]: https://github.com/rust-lang/rust/pull/30672 [1.7h]: https://github.com/rust-lang/rust/pull/30818 [1.7j]: https://github.com/rust-lang/rust/pull/30711 @@ -140,7 +140,7 @@ Compatibility Notes [1.7m]: https://github.com/rust-lang/rust/pull/30381 [1.7p]: https://github.com/rust-lang/rust/pull/30681 [1.7rp]: https://github.com/rust-lang/rust/pull/29498 -[1.7rp]: https://github.com/rust-lang/rust/pull/30353 +[1.7rpa]: https://github.com/rust-lang/rust/pull/30353 [1.7rr]: https://github.com/rust-lang/cargo/pull/2279 [1.7sf]: https://github.com/rust-lang/rust/pull/30389 [1.7utf8]: https://github.com/rust-lang/rust/pull/30740 diff --git a/src/doc/book/ownership.md b/src/doc/book/ownership.md index 175960f67b6..8f15544b20b 100644 --- a/src/doc/book/ownership.md +++ b/src/doc/book/ownership.md @@ -124,21 +124,65 @@ special annotation here, it’s the default thing that Rust does. ## The details The reason that we cannot use a binding after we’ve moved it is subtle, but -important. When we write code like this: +important. + +When we write code like this: + +```rust +let x = 10; +``` + +Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit +pattern representing the value of 10 to the allocated memory and binds the +variable name x to this memory region for future reference. + +Now consider the following code fragment: ```rust let v = vec![1, 2, 3]; -let v2 = v; +let mut v2 = v; ``` -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. +The first line allocates memory for the vector object `v` on the stack like +it does for `x` above. But in addition to that it also allocates some memory +on the [heap][sh] for the actual data (`[1, 2, 3]`). Rust copies the address +of this heap allocation to an internal pointer, which is part of the vector +object placed on the stack (let's call it the data pointer). + +It is worth pointing out (even at the risk of stating the obvious) that the +vector object and its data live in separate memory regions instead of being a +single contiguous memory allocation (due to reasons we will not go into at +this point of time). These two parts of the vector (the one on the stack and +one on the heap) must agree with each other at all times with regards to +things like the length, capacity etc. + +When we move `v` to `v2`, rust actually does a bitwise copy of the vector +object `v` into the stack allocation represented by `v2`. This shallow copy +does not create a copy of the heap allocation containing the actual data. +Which means that there would be two pointers to the contents of the vector +both pointing to the same memory allocation on the heap. It would violate +Rust’s safety guarantees by introducing a data race if one could access both +`v` and `v2` at the same time. + +For example if we truncated the vector to just two elements through `v2`: + +```rust +# let v = vec![1, 2, 3]; +# let mut v2 = v; +v2.truncate(2); +``` + +and `v1` were still accessible we'd end up with an invalid vector since `v1` +would not know that the heap data has been truncated. Now, the part of the +vector `v1` on the stack does not agree with the corresponding part on the +heap. `v1` still thinks there are three elements in the vector and will +happily let us access the non existent element `v1[2]` but as you might +already know this is a recipe for disaster. Especially because it might lead +to a segmentation fault or worse allow an unauthorized user to read from +memory to which they don't have access. + +This is why Rust forbids using `v` after we’ve done the move. [sh]: the-stack-and-the-heap.html diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 0ced4e1952a..7207e7b151c 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -375,9 +375,10 @@ pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where K: Borrow< /// /// If the map did not have this key present, `None` is returned. /// - /// If the map did have this key present, the key is not updated, the - /// value is updated and the old value is returned. - /// See the [module-level documentation] for more. + /// If the map did have this key present, the value is updated, and the old + /// value is returned. The key is not updated, though; this matters for + /// types that can be `==` without being identical. See the [module-level + /// documentation] for more. /// /// [module-level documentation]: index.html#insert-and-complex-keys /// diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index a521700b84b..c36ad592ad3 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -571,9 +571,25 @@ macro_rules! repeat_u8_as_u64 { /// ``` /// use std::mem; /// -/// let one = unsafe { mem::transmute_copy(&1) }; +/// #[repr(packed)] +/// struct Foo { +/// bar: u8, +/// } /// -/// assert_eq!(1, one); +/// let foo_slice = [10u8]; +/// +/// unsafe { +/// // Copy the data from 'foo_slice' and treat it as a 'Foo' +/// let mut foo_struct: Foo = mem::transmute_copy(&foo_slice); +/// assert_eq!(foo_struct.bar, 10); +/// +/// // Modify the copied data +/// foo_struct.bar = 20; +/// assert_eq!(foo_struct.bar, 20); +/// } +/// +/// // The contents of 'foo_slice' should not have changed +/// assert_eq!(foo_slice, [10]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 8a9ef666b83..92db527ef98 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -20,8 +20,8 @@ will never be reached as for all possible values of the expression being matched, one of the preceding patterns will match. -This means that perhaps some of the preceding patterns are too general, this one -is too specific or the ordering is incorrect. +This means that perhaps some of the preceding patterns are too general, this +one is too specific or the ordering is incorrect. For example, the following `match` block has too many arms: @@ -104,28 +104,86 @@ fn foo(x: Option) { This error indicates that the compiler cannot guarantee a matching pattern for one or more possible inputs to a match expression. Guaranteed matches are required in order to assign values to match expressions, or alternatively, -determine the flow of execution. +determine the flow of execution. Erroneous code example: + +```compile_fail +enum Terminator { + HastaLaVistaBaby, + TalkToMyHand, +} + +let x = Terminator::HastaLaVistaBaby; + +match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered + Terminator::TalkToMyHand => {} +} +``` If you encounter this error you must alter your patterns so that every possible value of the input type is matched. For types with a small number of variants (like enums) you should probably cover all cases explicitly. Alternatively, the underscore `_` wildcard pattern can be added after all other patterns to match -"anything else". +"anything else". Example: + +``` +enum Terminator { + HastaLaVistaBaby, + TalkToMyHand, +} + +let x = Terminator::HastaLaVistaBaby; + +match x { + Terminator::TalkToMyHand => {} + Terminator::HastaLaVistaBaby => {} +} + +// or: + +match x { + Terminator::TalkToMyHand => {} + _ => {} +} +``` "##, E0005: r##" Patterns used to bind names must be irrefutable, that is, they must guarantee -that a name will be extracted in all cases. If you encounter this error you -probably need to use a `match` or `if let` to deal with the possibility of -failure. +that a name will be extracted in all cases. Erroneous code example: + +```compile_fail +let x = Some(1); +let Some(y) = x; +// error: refutable pattern in local binding: `None` not covered +``` + +If you encounter this error you probably need to use a `match` or `if let` to +deal with the possibility of failure. Example: + +```compile_fail +let x = Some(1); + +match x { + Some(y) => { + // do something + }, + None => {} +} + +// or: + +if let Some(y) = x { + // do something +} +``` "##, E0007: r##" This error indicates that the bindings in a match arm would require a value to -be moved into more than one location, thus violating unique ownership. Code like -the following is invalid as it requires the entire `Option` to be moved -into a variable called `op_string` while simultaneously requiring the inner -String to be moved into a variable called `s`. +be moved into more than one location, thus violating unique ownership. Code +like the following is invalid as it requires the entire `Option` to be +moved into a variable called `op_string` while simultaneously requiring the +inner `String` to be moved into a variable called `s`. ```compile_fail let x = Some("s".to_string()); @@ -180,7 +238,7 @@ fn foo(x: Option) { This limitation may be removed in a future version of Rust. -Wrong example: +Erroneous code example: ```compile_fail struct X { x: (), } @@ -264,7 +322,7 @@ trait Foo where Self: Sized { } ``` -we cannot create an object of type `Box` or `&Foo` since in this case +We cannot create an object of type `Box` or `&Foo` since in this case `Self` would not be `Sized`. Generally, `Self : Sized` is used to indicate that the trait should not be used @@ -294,7 +352,7 @@ fn foo(&self) -> Self { ``` (Note that `&self` and `&mut self` are okay, it's additional `Self` types which -cause this problem) +cause this problem.) In such a case, the compiler cannot predict the return type of `foo()` in a situation like the following: @@ -573,15 +631,15 @@ struct ListNode { "##, E0133: r##" -Using unsafe functionality, is potentially dangerous and disallowed -by safety checks. Examples: +Using unsafe functionality is potentially dangerous and disallowed by safety +checks. Examples: -- Dereferencing raw pointers -- Calling functions via FFI -- Calling functions marked unsafe +* Dereferencing raw pointers +* Calling functions via FFI +* Calling functions marked unsafe -These safety checks can be relaxed for a section of the code -by wrapping the unsafe instructions with an `unsafe` block. For instance: +These safety checks can be relaxed for a section of the code by wrapping the +unsafe instructions with an `unsafe` block. For instance: ``` unsafe fn f() { return; } @@ -1039,14 +1097,16 @@ fn foo() -> ! { println!("{}", y); ``` -In the previous example, the print statement was never reached when the wildcard -match arm was hit, so we were okay with `foo()` not returning an integer that we -could set to `y`. But in this example, `foo()` actually does return control, so -the print statement will be executed with an uninitialized value. +In the previous example, the print statement was never reached when the +wildcard match arm was hit, so we were okay with `foo()` not returning an +integer that we could set to `y`. But in this example, `foo()` actually does +return control, so the print statement will be executed with an uninitialized +value. Obviously we cannot have functions which are allowed to be used in such positions and yet can return control. So, if you are defining a function that -returns `!`, make sure that there is no way for it to actually finish executing. +returns `!`, make sure that there is no way for it to actually finish +executing. "##, E0271: r##" @@ -1206,19 +1266,19 @@ trait Index { ... } foo(true); // `bool` does not implement `Index` ``` -there will be an error about `bool` not implementing `Index`, followed by a +There will be an error about `bool` not implementing `Index`, followed by a note saying "the type `bool` cannot be indexed by `u8`". -As you can see, you can specify type parameters in curly braces for substitution -with the actual types (using the regular format string syntax) in a given -situation. Furthermore, `{Self}` will substitute to the type (in this case, -`bool`) that we tried to use. +As you can see, you can specify type parameters in curly braces for +substitution with the actual types (using the regular format string syntax) in +a given situation. Furthermore, `{Self}` will substitute to the type (in this +case, `bool`) that we tried to use. This error appears when the curly braces contain an identifier which doesn't -match with any of the type parameters or the string `Self`. This might happen if -you misspelled a type parameter, or if you intended to use literal curly braces. -If it is the latter, escape the curly braces with a second curly brace of the -same type; e.g. a literal `{` is `{{` +match with any of the type parameters or the string `Self`. This might happen +if you misspelled a type parameter, or if you intended to use literal curly +braces. If it is the latter, escape the curly braces with a second curly brace +of the same type; e.g. a literal `{` is `{{`. "##, E0273: r##" @@ -1239,10 +1299,10 @@ trait Index { ... } there will be an error about `bool` not implementing `Index`, followed by a note saying "the type `bool` cannot be indexed by `u8`". -As you can see, you can specify type parameters in curly braces for substitution -with the actual types (using the regular format string syntax) in a given -situation. Furthermore, `{Self}` will substitute to the type (in this case, -`bool`) that we tried to use. +As you can see, you can specify type parameters in curly braces for +substitution with the actual types (using the regular format string syntax) in +a given situation. Furthermore, `{Self}` will substitute to the type (in this +case, `bool`) that we tried to use. This error appears when the curly braces do not contain an identifier. Please add one of the same name as a type parameter. If you intended to use literal @@ -1274,8 +1334,8 @@ trait Index { ... } E0275: r##" This error occurs when there was a recursive trait requirement that overflowed -before it could be evaluated. Often this means that there is unbounded recursion -in resolving some type bounds. +before it could be evaluated. Often this means that there is unbounded +recursion in resolving some type bounds. For example, in the following code: @@ -1288,9 +1348,9 @@ impl Foo for T where Bar: Foo {} ``` To determine if a `T` is `Foo`, we need to check if `Bar` is `Foo`. However, -to do this check, we need to determine that `Bar>` is `Foo`. To determine -this, we check if `Bar>>` is `Foo`, and so on. This is clearly a -recursive requirement that can't be resolved directly. +to do this check, we need to determine that `Bar>` is `Foo`. To +determine this, we check if `Bar>>` is `Foo`, and so on. This is +clearly a recursive requirement that can't be resolved directly. Consider changing your trait bounds so that they're less self-referential. "##, @@ -1336,7 +1396,7 @@ fn main() { // we now call the method with the i32 type, which doesn't implement // the Foo trait some_func(5i32); // error: the trait `Foo` is not implemented for the - // type `i32` + // type `i32` } ``` @@ -1564,7 +1624,9 @@ fn main() { ```compile_fail match Some(()) { None => { }, - option if option.take().is_none() => { /* impossible, option is `Some` */ }, + option if option.take().is_none() => { + /* impossible, option is `Some` */ + }, Some(_) => { } // When the previous match failed, the option became `None`. } ``` @@ -1615,12 +1677,29 @@ fn main() { E0306: r##" In an array literal `[x; N]`, `N` is the number of elements in the array. This -number cannot be negative. +must be an unsigned integer. Erroneous code example: + +```compile_fail +let x = [0i32; true]; // error: expected positive integer for repeat count, + // found boolean +``` + +Working example: + +``` +let x = [0i32; 2]; +``` "##, E0307: r##" -The length of an array is part of its type. For this reason, this length must be -a compile-time constant. +The length of an array is part of its type. For this reason, this length must +be a compile-time constant. Erroneous code example: + +```compile_fail + let len = 10; + let x = [0i32; len]; // error: expected constant integer for repeat count, + // found variable +``` "##, E0308: r##" @@ -1713,24 +1792,22 @@ struct Foo { "##, E0398: r##" -In Rust 1.3, the default object lifetime bounds are expected to -change, as described in RFC #1156 [1]. You are getting a warning -because the compiler thinks it is possible that this change will cause -a compilation error in your code. It is possible, though unlikely, -that this is a false alarm. +In Rust 1.3, the default object lifetime bounds are expected to change, as +described in RFC #1156 [1]. You are getting a warning because the compiler +thinks it is possible that this change will cause a compilation error in your +code. It is possible, though unlikely, that this is a false alarm. -The heart of the change is that where `&'a Box` used to -default to `&'a Box`, it now defaults to `&'a -Box` (here, `SomeTrait` is the name of some trait -type). Note that the only types which are affected are references to -boxes, like `&Box` or `&[Box]`. More common -types like `&SomeTrait` or `Box` are unaffected. +The heart of the change is that where `&'a Box` used to default to +`&'a Box`, it now defaults to `&'a Box` (here, +`SomeTrait` is the name of some trait type). Note that the only types which are +affected are references to boxes, like `&Box` or +`&[Box]`. More common types like `&SomeTrait` or `Box` +are unaffected. -To silence this warning, edit your code to use an explicit bound. -Most of the time, this means that you will want to change the -signature of a function that you are calling. For example, if -the error is reported on a call like `foo(x)`, and `foo` is -defined as follows: +To silence this warning, edit your code to use an explicit bound. Most of the +time, this means that you will want to change the signature of a function that +you are calling. For example, if the error is reported on a call like `foo(x)`, +and `foo` is defined as follows: ```ignore fn foo(arg: &Box) { ... } @@ -1742,8 +1819,8 @@ fn foo(arg: &Box) { ... } fn foo<'a>(arg: &Box) { ... } ``` -This explicitly states that you expect the trait object `SomeTrait` to -contain references (with a maximum lifetime of `'a`). +This explicitly states that you expect the trait object `SomeTrait` to contain +references (with a maximum lifetime of `'a`). [1]: https://github.com/rust-lang/rfcs/pull/1156 "##, @@ -1812,8 +1889,8 @@ fn foo() {} "##, E0517: r##" -This error indicates that a `#[repr(..)]` attribute was placed on an unsupported -item. +This error indicates that a `#[repr(..)]` attribute was placed on an +unsupported item. Examples of erroneous code: @@ -1829,29 +1906,29 @@ struct Foo {bar: bool, baz: bool} #[repr(C)] impl Foo { - ... + // ... } ``` - - The `#[repr(C)]` attribute can only be placed on structs and enums - - The `#[repr(packed)]` and `#[repr(simd)]` attributes only work on structs - - The `#[repr(u8)]`, `#[repr(i16)]`, etc attributes only work on enums +* The `#[repr(C)]` attribute can only be placed on structs and enums. +* The `#[repr(packed)]` and `#[repr(simd)]` attributes only work on structs. +* The `#[repr(u8)]`, `#[repr(i16)]`, etc attributes only work on enums. These attributes do not work on typedefs, since typedefs are just aliases. Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the -discriminant size for C-like enums (when there is no associated data, e.g. `enum -Color {Red, Blue, Green}`), effectively setting the size of the enum to the size -of the provided type. Such an enum can be cast to a value of the same type as -well. In short, `#[repr(u8)]` makes the enum behave like an integer with a -constrained set of allowed values. +discriminant size for C-like enums (when there is no associated data, e.g. +`enum Color {Red, Blue, Green}`), effectively setting the size of the enum to +the size of the provided type. Such an enum can be cast to a value of the same +type as well. In short, `#[repr(u8)]` makes the enum behave like an integer +with a constrained set of allowed values. Only C-like enums can be cast to numerical primitives, so this attribute will not apply to structs. `#[repr(packed)]` reduces padding to make the struct size smaller. The -representation of enums isn't strictly defined in Rust, and this attribute won't -work on enums. +representation of enums isn't strictly defined in Rust, and this attribute +won't work on enums. `#[repr(simd)]` will give a struct consisting of a homogenous series of machine types (i.e. `u8`, `i32`, etc) a representation that permits vectorization via @@ -1860,8 +1937,8 @@ impl Foo { "##, E0518: r##" -This error indicates that an `#[inline(..)]` attribute was incorrectly placed on -something other than a function or method. +This error indicates that an `#[inline(..)]` attribute was incorrectly placed +on something other than a function or method. Examples of erroneous code: @@ -1871,7 +1948,7 @@ impl Foo { #[inline(never)] impl Foo { - ... + // ... } ``` diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index 29944aaf367..7f6fd9de3d2 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -26,7 +26,8 @@ fn foo() -> Box u32> { Notice that `x` is stack-allocated by `foo()`. By default, Rust captures closed-over data by reference. This means that once `foo()` returns, `x` no -longer exists. An attempt to access `x` within the closure would thus be unsafe. +longer exists. An attempt to access `x` within the closure would thus be +unsafe. Another situation where this might be encountered is when spawning threads: @@ -73,7 +74,14 @@ fn main() { ``` To fix this, ensure that any declared variables are initialized before being -used. +used. Example: + +``` +fn main() { + let x: i32 = 0; + let y = x; // ok! +} +``` "##, E0382: r##" @@ -210,8 +218,8 @@ fn main(){ **y = 2; ``` -It can also be fixed by using a type with interior mutability, such as `Cell` or -`RefCell`: +It can also be fixed by using a type with interior mutability, such as `Cell` +or `RefCell`: ``` use std::cell::Cell; @@ -259,8 +267,8 @@ fn foo(f: F) { } ``` Alternatively, we can consider using the `Cell` and `RefCell` types to achieve -interior mutability through a shared reference. Our example's `mutable` function -could be redefined as below: +interior mutability through a shared reference. Our example's `mutable` +function could be redefined as below: ``` use std::cell::Cell; diff --git a/src/librustc_privacy/diagnostics.rs b/src/librustc_privacy/diagnostics.rs index d124ead5091..36ba3d0ca73 100644 --- a/src/librustc_privacy/diagnostics.rs +++ b/src/librustc_privacy/diagnostics.rs @@ -27,8 +27,8 @@ pub fn foo (t: T) {} // same error ``` To solve this error, please ensure that the trait is also public. The trait -can be made inaccessible if necessary by placing it into a private inner module, -but it still has to be marked with `pub`. Example: +can be made inaccessible if necessary by placing it into a private inner +module, but it still has to be marked with `pub`. Example: ```ignore pub trait Foo { // we set the Foo trait public @@ -55,8 +55,8 @@ pub fn bar() -> Bar { // error: private type in public interface ``` To solve this error, please ensure that the type is also public. The type -can be made inaccessible if necessary by placing it into a private inner module, -but it still has to be marked with `pub`. +can be made inaccessible if necessary by placing it into a private inner +module, but it still has to be marked with `pub`. Example: ``` @@ -165,7 +165,7 @@ mod Bar { ``` To solve this issue, please ensure that all of the fields of the tuple struct -are public. Alternatively, provide a new() method to the tuple struct to +are public. Alternatively, provide a `new()` method to the tuple struct to construct it from a given inner value. Example: ``` diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 99c29bbb8ef..dee2727c163 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -94,8 +94,8 @@ pub mod baz {} "##, E0253: r##" -Attempt was made to import an unimportable value. This can happen when -trying to import a method from a trait. An example of this error: +Attempt was made to import an unimportable value. This can happen when trying +to import a method from a trait. An example of this error: ```compile_fail mod foo { @@ -149,10 +149,10 @@ fn main() {} "##, E0259: r##" -The name chosen for an external crate conflicts with another external crate that -has been imported into the current module. +The name chosen for an external crate conflicts with another external crate +that has been imported into the current module. -Wrong example: +Erroneous code example: ```compile_fail extern crate a; @@ -251,8 +251,8 @@ impl MyTrait for Option { "##, E0364: r##" -Private items cannot be publicly re-exported. This error indicates that -you attempted to `pub use` a type or value that was not itself public. +Private items cannot be publicly re-exported. This error indicates that you +attempted to `pub use` a type or value that was not itself public. Here is an example that demonstrates the error: @@ -275,15 +275,15 @@ mod foo { pub use foo::X; ``` -See the 'Use Declarations' section of the reference for more information -on this topic: +See the 'Use Declarations' section of the reference for more information on +this topic: https://doc.rust-lang.org/reference.html#use-declarations "##, E0365: r##" -Private modules cannot be publicly re-exported. This error indicates -that you attempted to `pub use` a module that was not itself public. +Private modules cannot be publicly re-exported. This error indicates that you +attempted to `pub use` a module that was not itself public. Here is an example that demonstrates the error: @@ -313,8 +313,8 @@ pub mod foo { "##, E0401: r##" -Inner items do not inherit type parameters from the functions they are -embedded in. For example, this will not compile: +Inner items do not inherit type parameters from the functions they are embedded +in. For example, this will not compile: ```compile_fail fn foo(x: T) { @@ -543,16 +543,15 @@ fn b() {} "##, E0411: r##" -The `Self` keyword was used outside an impl or a trait. Erroneous -code example: +The `Self` keyword was used outside an impl or a trait. Erroneous code example: ```compile_fail ::foo; // error: use of `Self` outside of an impl or trait ``` -The `Self` keyword represents the current type, which explains why it -can only be used inside an impl or a trait. It gives access to the -associated items of a type: +The `Self` keyword represents the current type, which explains why it can only +be used inside an impl or a trait. It gives access to the associated items of a +type: ``` trait Foo { @@ -564,7 +563,7 @@ trait Baz : Foo { } ``` -However, be careful when two types has a common associated type: +However, be careful when two types have a common associated type: ```compile_fail trait Foo { @@ -581,8 +580,8 @@ trait Baz : Foo + Foo2 { } ``` -This problem can be solved by specifying from which trait we want -to use the `Bar` type: +This problem can be solved by specifying from which trait we want to use the +`Bar` type: ``` trait Foo { @@ -604,16 +603,20 @@ trait Baz : Foo + Foo2 { ```compile_fail impl Something {} // error: use of undeclared type name `Something` + // or: + trait Foo { fn bar(N); // error: use of undeclared type name `N` } + // or: + fn foo(x: T) {} // error: use of undeclared type name `T` ``` -To fix this error, please verify you didn't misspell the type name, -you did declare it or imported it into the scope. Examples: +To fix this error, please verify you didn't misspell the type name, you did +declare it or imported it into the scope. Examples: ``` struct Something; @@ -635,8 +638,8 @@ fn foo(x: T) {} // ok! "##, E0413: r##" -A declaration shadows an enum variant or unit-like struct in scope. -Example of erroneous code: +A declaration shadows an enum variant or unit-like struct in scope. Example of +erroneous code: ```compile_fail struct Foo; @@ -666,8 +669,7 @@ fn foo(x: T) {} // ok! "##, E0415: r##" -More than one function parameter have the same name. Example of erroneous -code: +More than one function parameter have the same name. Example of erroneous code: ```compile_fail fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than @@ -682,8 +684,7 @@ fn foo(f: i32, g: i32) {} // ok! "##, E0416: r##" -An identifier is bound more than once in a pattern. Example of erroneous -code: +An identifier is bound more than once in a pattern. Example of erroneous code: ```compile_fail match (1, 2) { @@ -739,8 +740,7 @@ fn foo(f: i32, g: i32) {} // ok! "##, E0419: r##" -An unknown enum variant, struct or const was used. Example of -erroneous code: +An unknown enum variant, struct or const was used. Example of erroneous code: ```compile_fail match 0 { @@ -766,8 +766,8 @@ enum Something { "##, E0422: r##" -You are trying to use an identifier that is either undefined or not a -struct. For instance: +You are trying to use an identifier that is either undefined or not a struct. +For instance: ``` compile_fail fn main () { @@ -785,13 +785,13 @@ fn main () { } ``` -In this case, `foo` is defined, but is not a struct, so Rust can't use -it as one. +In this case, `foo` is defined, but is not a struct, so Rust can't use it as +one. "##, E0423: r##" -A `struct` variant name was used like a function name. Example of -erroneous code: +A `struct` variant name was used like a function name. Example of erroneous +code: ```compile_fail struct Foo { a: bool}; @@ -801,8 +801,8 @@ fn main () { // it like a function name ``` -Please verify you didn't misspell the name of what you actually wanted -to use here. Example: +Please verify you didn't misspell the name of what you actually wanted to use +here. Example: ``` fn Foo() -> u32 { 0 } @@ -851,6 +851,7 @@ fn foo(self) { // error: unresolved name `something_that_doesnt_exist::foo` // or: + trait Foo { fn bar() { Self; // error: unresolved name `Self` @@ -858,6 +859,7 @@ fn bar() { } // or: + let x = unknown_variable; // error: unresolved name `unknown_variable` ``` @@ -941,7 +943,7 @@ mod something_that_does_exist { "##, E0431: r##" -`self` import was made. Erroneous code example: +An invalid `self` import was made. Erroneous code example: ```compile_fail use {self}; // error: `self` import can only appear in an import list with a diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 586fafc2b4a..7220690469c 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1157,9 +1157,10 @@ pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> /// /// If the map did not have this key present, `None` is returned. /// - /// If the map did have this key present, the key is not updated, the - /// value is updated and the old value is returned. - /// See the [module-level documentation] for more. + /// If the map did have this key present, the value is updated, and the old + /// value is returned. The key is not updated, though; this matters for + /// types that can be `==` without being identical. See the [module-level + /// documentation] for more. /// /// [module-level documentation]: index.html#insert-and-complex-keys /// diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 417261cf4c3..06c14157606 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -397,12 +397,15 @@ //! } //! //! let mut map = BTreeMap::new(); -//! map.insert(Foo { a: 1, b: "baz" }, ()); +//! map.insert(Foo { a: 1, b: "baz" }, 99); //! //! // We already have a Foo with an a of 1, so this will be updating the value. -//! map.insert(Foo { a: 1, b: "xyz" }, ()); +//! map.insert(Foo { a: 1, b: "xyz" }, 100); //! -//! // ... but the key hasn't changed. b is still "baz", not "xyz" +//! // The value has been updated... +//! assert_eq!(map.values().next().unwrap(), &100); +//! +//! // ...but the key hasn't changed. b is still "baz", not "xyz". //! assert_eq!(map.keys().next().unwrap().b, "baz"); //! ``` diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 10ecaed3aef..3798fb76ad6 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1582,8 +1582,10 @@ pub fn relative_from<'a, P: ?Sized + AsRef>(&'a self, base: &'a P) -> Opti /// Returns a path that, when joined onto `base`, yields `self`. /// + /// # Errors + /// /// If `base` is not a prefix of `self` (i.e. `starts_with` - /// returns false), then `relative_from` returns `None`. + /// returns `false`), returns `Err`. #[stable(since = "1.7.0", feature = "path_strip_prefix")] pub fn strip_prefix<'a, P: ?Sized>(&'a self, base: &'a P) -> Result<&'a Path, StripPrefixError> diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index ad93fe0094a..b840e51873e 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -50,18 +50,21 @@ mod prim_bool { } /// [`String`]: string/struct.String.html /// /// As always, remember that a human intuition for 'character' may not map to -/// Unicode's definitions. For example, emoji symbols such as '❤️' are more than -/// one byte; ❤️ in particular is six: +/// Unicode's definitions. For example, emoji symbols such as '❤️' can be more +/// than one Unicode code point; this ❤️ in particular is two: /// /// ``` /// let s = String::from("❤️"); /// -/// // six bytes times one byte for each element -/// assert_eq!(6, s.len() * std::mem::size_of::()); +/// // we get two chars out of a single ❤️ +/// let mut iter = s.chars(); +/// assert_eq!(Some('\u{2764}'), iter.next()); +/// assert_eq!(Some('\u{fe0f}'), iter.next()); +/// assert_eq!(None, iter.next()); /// ``` /// -/// This also means it won't fit into a `char`, and so trying to create a -/// literal with `let heart = '❤️';` gives an error: +/// This means it won't fit into a `char`. Trying to create a literal with +/// `let heart = '❤️';` gives an error: /// /// ```text /// error: character literal may only contain one codepoint: '❤ @@ -69,8 +72,8 @@ mod prim_bool { } /// ^~ /// ``` /// -/// Another implication of this is that if you want to do per-`char`acter -/// processing, it can end up using a lot more memory: +/// Another implication of the 4-byte fixed size of a `char`, is that +/// per-`char`acter processing can end up using a lot more memory: /// /// ``` /// let s = String::from("love: ❤️"); @@ -79,19 +82,6 @@ mod prim_bool { } /// assert_eq!(12, s.len() * std::mem::size_of::()); /// assert_eq!(32, v.len() * std::mem::size_of::()); /// ``` -/// -/// Or may give you results you may not expect: -/// -/// ``` -/// let s = String::from("❤️"); -/// -/// let mut iter = s.chars(); -/// -/// // we get two chars out of a single ❤️ -/// assert_eq!(Some('\u{2764}'), iter.next()); -/// assert_eq!(Some('\u{fe0f}'), iter.next()); -/// assert_eq!(None, iter.next()); -/// ``` mod prim_char { } #[doc(primitive = "unit")]