Auto merge of #31739 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #31565, #31679, #31694, #31695, #31703, #31720, #31733 - Failed merges:
This commit is contained in:
commit
e18f7a1c5a
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -375,9 +375,10 @@ pub fn get_mut<Q: ?Sized>(&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
|
||||
///
|
||||
|
@ -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")]
|
||||
|
@ -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<String>) {
|
||||
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<String>` 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<String>` 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<String>) {
|
||||
|
||||
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<Foo>` or `&Foo` since in this case
|
||||
We cannot create an object of type `Box<Foo>` 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<Idx> { ... }
|
||||
foo(true); // `bool` does not implement `Index<u8>`
|
||||
```
|
||||
|
||||
there will be an error about `bool` not implementing `Index<u8>`, followed by a
|
||||
There will be an error about `bool` not implementing `Index<u8>`, 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<Idx> { ... }
|
||||
there will be an error about `bool` not implementing `Index<u8>`, 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<Idx> { ... }
|
||||
|
||||
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<T> Foo for T where Bar<T>: Foo {}
|
||||
```
|
||||
|
||||
To determine if a `T` is `Foo`, we need to check if `Bar<T>` is `Foo`. However,
|
||||
to do this check, we need to determine that `Bar<Bar<T>>` is `Foo`. To determine
|
||||
this, we check if `Bar<Bar<Bar<T>>>` 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<Bar<T>>` is `Foo`. To
|
||||
determine this, we check if `Bar<Bar<Bar<T>>>` 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.
|
||||
"##,
|
||||
@ -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<T: 'static> {
|
||||
"##,
|
||||
|
||||
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<SomeTrait>` used to
|
||||
default to `&'a Box<SomeTrait+'a>`, it now defaults to `&'a
|
||||
Box<SomeTrait+'static>` (here, `SomeTrait` is the name of some trait
|
||||
type). Note that the only types which are affected are references to
|
||||
boxes, like `&Box<SomeTrait>` or `&[Box<SomeTrait>]`. More common
|
||||
types like `&SomeTrait` or `Box<SomeTrait>` are unaffected.
|
||||
The heart of the change is that where `&'a Box<SomeTrait>` used to default to
|
||||
`&'a Box<SomeTrait+'a>`, it now defaults to `&'a Box<SomeTrait+'static>` (here,
|
||||
`SomeTrait` is the name of some trait type). Note that the only types which are
|
||||
affected are references to boxes, like `&Box<SomeTrait>` or
|
||||
`&[Box<SomeTrait>]`. More common types like `&SomeTrait` or `Box<SomeTrait>`
|
||||
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<SomeTrait>) { ... }
|
||||
@ -1742,8 +1819,8 @@ fn foo(arg: &Box<SomeTrait>) { ... }
|
||||
fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
|
||||
```
|
||||
|
||||
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 {
|
||||
...
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -26,7 +26,8 @@ fn foo() -> Box<Fn(u32) -> 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: FnMut()>(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;
|
||||
|
@ -27,8 +27,8 @@ pub fn foo<T: 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:
|
||||
|
||||
```
|
||||
|
@ -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<u8> {
|
||||
"##,
|
||||
|
||||
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<T>(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
|
||||
<Self>::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<T>(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<T>(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
|
||||
|
@ -1157,9 +1157,10 @@ pub fn get_mut<Q: ?Sized>(&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
|
||||
///
|
||||
|
@ -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");
|
||||
//! ```
|
||||
|
||||
|
@ -1582,8 +1582,10 @@ pub fn relative_from<'a, P: ?Sized + AsRef<Path>>(&'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>
|
||||
|
@ -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::<u8>());
|
||||
/// // 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::<u8>());
|
||||
/// assert_eq!(32, v.len() * std::mem::size_of::<char>());
|
||||
/// ```
|
||||
///
|
||||
/// 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")]
|
||||
|
Loading…
Reference in New Issue
Block a user