| //@ dont-require-annotations: NOTE | |
| #![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)] | |
| 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 = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { | |
| //~^ NOTE `significant_drop::Client` which is not `Send` | |
| //~| NOTE `insignificant_dtor::Client` which is not `Send` | |
| //~| NOTE `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 = #[coroutine] 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) {} | |
| } | |
| }; | |
| ); | |
| } |