Rollup merge of #138628 - spastorino:add-more-ergonomic-clone-tests, r=nikomatsakis

Add more ergonomic clone tests

I've added some extra tests.

r? `@nikomatsakis`
This commit is contained in:
Matthias Krüger 2025-04-09 20:23:09 +02:00 committed by GitHub
commit 3507f359b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 137 additions and 0 deletions

View File

@ -0,0 +1,35 @@
#![feature(ergonomic_clones)]
#![allow(incomplete_features)]
use std::clone::UseCloned;
fn takes_val<T>(_: T) {}
fn takes_ref<'a, T>(_: &'a T) {}
#[derive(Clone)]
struct Inner<'a, T>(&'a T);
impl<'a, T> UseCloned for Inner<'a, T> where T: Clone {}
fn main() {
let v = String::new();
let inner = Inner(&v);
let _ = use || {
takes_ref(inner.0);
takes_val(inner.0)
};
let _ = use || {
takes_ref(inner.0);
takes_val(inner.0);
takes_val(inner.0);
takes_val(inner)
};
let _ = use || {
takes_ref(inner.0);
takes_val(inner.0);
takes_val(inner);
takes_val(inner)
//~^ ERROR: use of moved value: `inner` [E0382]
};
}

View File

@ -0,0 +1,13 @@
error[E0382]: use of moved value: `inner`
--> $DIR/multiple-use-variants.rs:32:19
|
LL | takes_val(inner);
| ----- value moved here
LL | takes_val(inner)
| ^^^^^ value used here after move
|
= note: move occurs because `inner` has type `Inner<'_, String>`, which does not implement the `Copy` trait
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0382`.

View File

@ -0,0 +1,28 @@
error[E0382]: use of moved value: `x`
--> $DIR/spawn-thread.rs:15:42
|
LL | let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
| - move occurs because `x` has type `(Arc<String>, Arc<Vec<i32>>, Arc<i32>)`, which does not implement the `Copy` trait
LL | for _ in 0..10 {
| -------------- inside of this loop
LL | let handler = std::thread::spawn(use || {
| __________________________________________-^^^^^
LL | |
LL | | drop((x.0, x.1, x.2));
| | --- use occurs due to use in closure
LL | | });
| |_________- value moved here, in previous iteration of loop
|
help: consider moving the expression out of the loop so it is only moved once
|
LL ~ let mut value = std::thread::spawn(use || {
LL +
LL + drop((x.0, x.1, x.2));
LL + });
LL ~ for _ in 0..10 {
LL ~ let handler = value;
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0382`.

View File

@ -0,0 +1,50 @@
//@ revisions: edition2018 edition2024
//@ [edition2018] edition: 2018
//@ [edition2024] edition: 2024
//@ [edition2024] check-pass
#![feature(ergonomic_clones)]
#![allow(incomplete_features)]
use std::sync::Arc;
fn foo() {
// The type is a tuple and doesn't implement UseCloned
let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
for _ in 0..10 {
let handler = std::thread::spawn(use || {
//[edition2018]~^ ERROR use of moved value: `x` [E0382]
drop((x.0, x.1, x.2));
});
handler.join().unwrap();
}
}
fn bar() {
let x = Arc::new("foo".to_owned());
let y = Arc::new(vec![1, 2, 3]);
let z = Arc::new(1);
for _ in 0..10 {
let handler = std::thread::spawn(use || {
drop((x, y, z));
});
handler.join().unwrap();
}
}
fn baz() {
use std::sync::Arc;
use std::thread;
let five = Arc::new(5);
for _ in 0..10 {
let handler = thread::spawn(use || {
println!("{five:?}");
});
handler.join().unwrap();
}
}
fn main() {}

View File

@ -0,0 +1,11 @@
//@ check-pass
#![feature(ergonomic_clones)]
#![allow(incomplete_features)]
fn use_block_test(x: i32) -> i32 {
let x = { let x = x + 1; x }.use;
x
}
fn main() {}