Auto merge of #32561 - steveklabnik:rollup, r=steveklabnik
Rollup of 7 pull requests - Successful merges: #32177, #32235, #32472, #32504, #32507, #32509, #32534 - Failed merges:
This commit is contained in:
commit
221c940bf3
@ -132,8 +132,8 @@ Some common make targets are:
|
||||
- `make check-stage1-std NO_REBUILD=1` - test the standard library without
|
||||
rebuilding the entire compiler
|
||||
- `make check TESTNAME=<substring-of-test-name>` - Run a matching set of tests.
|
||||
- `TESTNAME` should be a substring of the tests to match against e.g. it could
|
||||
be the fully qualified test name, or just a part of it.
|
||||
- `TESTNAME` should be a substring of the tests to match against e.g. it could
|
||||
be the fully qualified test name, or just a part of it.
|
||||
`TESTNAME=collections::hash::map::test_map::test_capacity_not_less_than_len`
|
||||
or `TESTNAME=test_capacity_not_less_than_len`.
|
||||
- `make check-stage1-rpass TESTNAME=<substring-of-test-name>` - Run a single
|
||||
|
@ -17,12 +17,12 @@ function result.
|
||||
The most common case of coercion is removing mutability from a reference:
|
||||
|
||||
* `&mut T` to `&T`
|
||||
|
||||
|
||||
An analogous conversion is to remove mutability from a
|
||||
[raw pointer](raw-pointers.md):
|
||||
|
||||
* `*mut T` to `*const T`
|
||||
|
||||
|
||||
References can also be coerced to raw pointers:
|
||||
|
||||
* `&T` to `*const T`
|
||||
@ -32,7 +32,7 @@ References can also be coerced to raw pointers:
|
||||
Custom coercions may be defined using [`Deref`](deref-coercions.md).
|
||||
|
||||
Coercion is transitive.
|
||||
|
||||
|
||||
# `as`
|
||||
|
||||
The `as` keyword does safe casting:
|
||||
@ -64,7 +64,7 @@ A cast `e as U` is also valid in any of the following cases:
|
||||
and `U` is an integer type; *enum-cast*
|
||||
* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
|
||||
* `e` has type `u8` and `U` is `char`; *u8-char-cast*
|
||||
|
||||
|
||||
For example
|
||||
|
||||
```rust
|
||||
@ -98,9 +98,9 @@ The semantics of numeric casts are:
|
||||
|
||||
[float-int]: https://github.com/rust-lang/rust/issues/10184
|
||||
[float-float]: https://github.com/rust-lang/rust/issues/15536
|
||||
|
||||
|
||||
## Pointer casts
|
||||
|
||||
|
||||
Perhaps surprisingly, it is safe to cast [raw pointers](raw-pointers.md) to and
|
||||
from integers, and to cast between pointers to different types subject to
|
||||
some constraints. It is only unsafe to dereference the pointer:
|
||||
@ -114,7 +114,7 @@ let b = a as u32;
|
||||
|
||||
* `e` has type `*T`, `U` has type `*U_0`, and either `U_0: Sized` or
|
||||
`unsize_kind(T) == unsize_kind(U_0)`; a *ptr-ptr-cast*
|
||||
|
||||
|
||||
* `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
|
||||
|
||||
* `e` is an integer and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
|
||||
|
@ -502,5 +502,5 @@ assert_eq!(6, answer);
|
||||
```
|
||||
|
||||
By making the inner closure a `move Fn`, we create a new stack frame for our
|
||||
closure. By `Box`ing it up, we’ve given it a known size, and allowing it to
|
||||
closure. By `Box`ing it up, we’ve given it a known size, allowing it to
|
||||
escape our stack frame.
|
||||
|
@ -72,7 +72,7 @@ a [`Drop`][drop] implementation.
|
||||
# Initializing
|
||||
|
||||
Both `const` and `static` have requirements for giving them a value. They must
|
||||
be given a value that’s a constant expression. In other words, you cannot use
|
||||
be given a value that’s a constant expression. In other words, you cannot use
|
||||
the result of a function call or anything similarly complex or at runtime.
|
||||
|
||||
# Which construct should I use?
|
||||
|
@ -417,7 +417,7 @@ first. This leaves the top-level project directory (in this case,
|
||||
to your code. In this way, using Cargo helps you keep your projects nice and
|
||||
tidy. There's a place for everything, and everything is in its place.
|
||||
|
||||
Now, copy *main.rs* to the *src* directory, and delete the compiled file you
|
||||
Now, move *main.rs* into the *src* directory, and delete the compiled file you
|
||||
created with `rustc`. As usual, replace `main` with `main.exe` if you're on
|
||||
Windows.
|
||||
|
||||
|
@ -337,8 +337,8 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Instead you need to pass the variable name into the invocation, so it’s tagged
|
||||
with the right syntax context.
|
||||
Instead you need to pass the variable name into the invocation, so that it’s
|
||||
tagged with the right syntax context.
|
||||
|
||||
```rust
|
||||
macro_rules! foo {
|
||||
@ -470,7 +470,7 @@ which syntactic form it matches.
|
||||
* `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`.
|
||||
* `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`.
|
||||
* `stmt`: a single statement. Example: `let x = 3`.
|
||||
* `block`: a brace-delimited sequence of statements. Example:
|
||||
* `block`: a brace-delimited sequence of statements and optionally an expression. Example:
|
||||
`{ log(error, "hi"); return 12; }`.
|
||||
* `item`: an [item][item]. Examples: `fn foo() { }`; `struct Bar;`.
|
||||
* `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`.
|
||||
|
@ -28,8 +28,8 @@ patterns][patterns] that covers all the patterns that are possible here.
|
||||
|
||||
[patterns]: patterns.html
|
||||
|
||||
One of the many advantages of `match` is it enforces ‘exhaustiveness checking’.
|
||||
For example if we remove the last arm with the underscore `_`, the compiler will
|
||||
One of the many advantages of `match` is it enforces ‘exhaustiveness checking’.
|
||||
For example if we remove the last arm with the underscore `_`, the compiler will
|
||||
give us an error:
|
||||
|
||||
```text
|
||||
@ -58,7 +58,7 @@ let number = match x {
|
||||
};
|
||||
```
|
||||
|
||||
Sometimes it’s a nice way of converting something from one type to another; in
|
||||
Sometimes it’s a nice way of converting something from one type to another; in
|
||||
this example the integers are converted to `String`.
|
||||
|
||||
# Matching on enums
|
||||
@ -90,7 +90,7 @@ fn process_message(msg: Message) {
|
||||
|
||||
Again, the Rust compiler checks exhaustiveness, so it demands that you
|
||||
have a match arm for every variant of the enum. If you leave one off, it
|
||||
will give you a compile-time error unless you use `_` or provide all possible
|
||||
will give you a compile-time error unless you use `_` or provide all possible
|
||||
arms.
|
||||
|
||||
Unlike the previous uses of `match`, you can’t use the normal `if`
|
||||
|
@ -124,7 +124,7 @@ 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.
|
||||
important.
|
||||
|
||||
When we write code like this:
|
||||
|
||||
@ -148,7 +148,7 @@ 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).
|
||||
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
|
||||
@ -163,7 +163,7 @@ 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.
|
||||
`v` and `v2` at the same time.
|
||||
|
||||
For example if we truncated the vector to just two elements through `v2`:
|
||||
|
||||
|
@ -164,7 +164,7 @@ copying. For example, you might want to reference only one line of a file read
|
||||
into memory. By nature, a slice is not created directly, but from an existing
|
||||
variable binding. Slices have a defined length, can be mutable or immutable.
|
||||
|
||||
Internally, slices are represented as a pointer to the beginning of the data
|
||||
Internally, slices are represented as a pointer to the beginning of the data
|
||||
and a length.
|
||||
|
||||
## Slicing syntax
|
||||
|
@ -116,7 +116,7 @@ for i in v {
|
||||
```
|
||||
|
||||
Note: You cannot use the vector again once you have iterated by taking ownership of the vector.
|
||||
You can iterate the vector multiple times by taking a reference to the vector whilst iterating.
|
||||
You can iterate the vector multiple times by taking a reference to the vector whilst iterating.
|
||||
For example, the following code does not compile.
|
||||
|
||||
```rust,ignore
|
||||
|
@ -107,7 +107,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
|
||||
/// use std::thread;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let numbers: Vec<_> = (0..100u32).collect();
|
||||
/// let numbers: Vec<_> = (0..100).collect();
|
||||
/// let shared_numbers = Arc::new(numbers);
|
||||
///
|
||||
/// for _ in 0..10 {
|
||||
@ -1118,7 +1118,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_strong_count() {
|
||||
let a = Arc::new(0u32);
|
||||
let a = Arc::new(0);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
let w = Arc::downgrade(&a);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
@ -1135,7 +1135,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_weak_count() {
|
||||
let a = Arc::new(0u32);
|
||||
let a = Arc::new(0);
|
||||
assert!(Arc::strong_count(&a) == 1);
|
||||
assert!(Arc::weak_count(&a) == 0);
|
||||
let w = Arc::downgrade(&a);
|
||||
@ -1161,7 +1161,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn show_arc() {
|
||||
let a = Arc::new(5u32);
|
||||
let a = Arc::new(5);
|
||||
assert_eq!(format!("{:?}", a), "5");
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_strong_count() {
|
||||
let a = Rc::new(0u32);
|
||||
let a = Rc::new(0);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
let w = Rc::downgrade(&a);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
@ -1031,7 +1031,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_weak_count() {
|
||||
let a = Rc::new(0u32);
|
||||
let a = Rc::new(0);
|
||||
assert!(Rc::strong_count(&a) == 1);
|
||||
assert!(Rc::weak_count(&a) == 0);
|
||||
let w = Rc::downgrade(&a);
|
||||
|
@ -1305,10 +1305,10 @@ mod tests {
|
||||
//
|
||||
// https://github.com/rust-lang/rust/issues/26021
|
||||
let mut v1 = LinkedList::new();
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
let _ = v1.split_off(3); // Dropping this now should not cause laundry consumption
|
||||
assert_eq!(v1.len(), 3);
|
||||
|
||||
@ -1319,10 +1319,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_split_off() {
|
||||
let mut v1 = LinkedList::new();
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1u8);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
v1.push_front(1);
|
||||
|
||||
// test all splits
|
||||
for ix in 0..1 + v1.len() {
|
||||
|
@ -267,9 +267,9 @@ fn test_swap_remove_fail() {
|
||||
fn test_swap_remove_noncopyable() {
|
||||
// Tests that we don't accidentally run destructors twice.
|
||||
let mut v: Vec<Box<_>> = Vec::new();
|
||||
v.push(box 0u8);
|
||||
v.push(box 0u8);
|
||||
v.push(box 0u8);
|
||||
v.push(box 0);
|
||||
v.push(box 0);
|
||||
v.push(box 0);
|
||||
let mut _e = v.swap_remove(0);
|
||||
assert_eq!(v.len(), 2);
|
||||
_e = v.swap_remove(1);
|
||||
@ -884,7 +884,7 @@ fn test_overflow_does_not_cause_segfault_managed() {
|
||||
|
||||
#[test]
|
||||
fn test_mut_split_at() {
|
||||
let mut values = [1u8,2,3,4,5];
|
||||
let mut values = [1,2,3,4,5];
|
||||
{
|
||||
let (left, right) = values.split_at_mut(2);
|
||||
{
|
||||
|
@ -327,6 +327,30 @@ fn main() {
|
||||
<Test as Trait1>::foo()
|
||||
}
|
||||
```
|
||||
|
||||
One last example:
|
||||
|
||||
```
|
||||
trait F {
|
||||
fn m(&self);
|
||||
}
|
||||
|
||||
trait G {
|
||||
fn m(&self);
|
||||
}
|
||||
|
||||
struct X;
|
||||
|
||||
impl F for X { fn m(&self) { println!("I am F"); } }
|
||||
impl G for X { fn m(&self) { println!("I am G"); } }
|
||||
|
||||
fn main() {
|
||||
let f = X;
|
||||
|
||||
F::m(&f); // it displays "I am F"
|
||||
G::m(&f); // it displays "I am G"
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0035: r##"
|
||||
|
@ -17,16 +17,21 @@ use sync::{Mutex, Condvar};
|
||||
/// use std::sync::{Arc, Barrier};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mut handles = Vec::with_capacity(10);
|
||||
/// let barrier = Arc::new(Barrier::new(10));
|
||||
/// for _ in 0..10 {
|
||||
/// let c = barrier.clone();
|
||||
/// // The same messages will be printed together.
|
||||
/// // You will NOT see any interleaving.
|
||||
/// thread::spawn(move|| {
|
||||
/// handles.push(thread::spawn(move|| {
|
||||
/// println!("before wait");
|
||||
/// c.wait();
|
||||
/// println!("after wait");
|
||||
/// });
|
||||
/// }));
|
||||
/// }
|
||||
/// // Wait for other threads to finish.
|
||||
/// for handle in handles {
|
||||
/// handle.join().unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
Loading…
Reference in New Issue
Block a user