70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
|
// compile-flags: -Zdrop-tracking
|
||
|
#![feature(generators, negative_impls, rustc_attrs)]
|
||
|
|
||
|
macro_rules! type_combinations {
|
||
|
(
|
||
|
$( $name:ident => { $( $tt:tt )* } );* $(;)?
|
||
|
) => { $(
|
||
|
mod $name {
|
||
|
$( $tt )*
|
||
|
|
||
|
impl !Sync for Client {}
|
||
|
impl !Send for Client {}
|
||
|
}
|
||
|
|
||
|
// Struct update syntax. This fails because the Client used in the update is considered
|
||
|
// dropped *after* the yield.
|
||
|
{
|
||
|
let g = move || match drop($name::Client { ..$name::Client::default() }) {
|
||
|
//~^ `significant_drop::Client` which is not `Send`
|
||
|
//~| `insignificant_dtor::Client` which is not `Send`
|
||
|
//~| `derived_drop::Client` which is not `Send`
|
||
|
_ => yield,
|
||
|
};
|
||
|
assert_send(g);
|
||
|
//~^ ERROR cannot be sent between threads
|
||
|
//~| ERROR cannot be sent between threads
|
||
|
//~| ERROR cannot be sent between threads
|
||
|
}
|
||
|
|
||
|
// Simple owned value. This works because the Client is considered moved into `drop`,
|
||
|
// even though the temporary expression doesn't end until after the yield.
|
||
|
{
|
||
|
let g = move || match drop($name::Client::default()) {
|
||
|
_ => yield,
|
||
|
};
|
||
|
assert_send(g);
|
||
|
}
|
||
|
)* }
|
||
|
}
|
||
|
|
||
|
fn assert_send<T: Send>(_thing: T) {}
|
||
|
|
||
|
fn main() {
|
||
|
type_combinations!(
|
||
|
// OK
|
||
|
copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
|
||
|
// NOT OK: MIR borrowck thinks that this is used after the yield, even though
|
||
|
// this has no `Drop` impl and only the drops of the fields are observable.
|
||
|
// FIXME: this should compile.
|
||
|
derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
|
||
|
// NOT OK
|
||
|
significant_drop => {
|
||
|
#[derive(Default)]
|
||
|
pub struct Client;
|
||
|
impl Drop for Client {
|
||
|
fn drop(&mut self) {}
|
||
|
}
|
||
|
};
|
||
|
// NOT OK (we need to agree with MIR borrowck)
|
||
|
insignificant_dtor => {
|
||
|
#[derive(Default)]
|
||
|
#[rustc_insignificant_dtor]
|
||
|
pub struct Client;
|
||
|
impl Drop for Client {
|
||
|
fn drop(&mut self) {}
|
||
|
}
|
||
|
};
|
||
|
);
|
||
|
}
|