// run-pass // Check that item-less traits do not cause dropck to inject extra // region constraints. #![allow(non_camel_case_types)] #![feature(dropck_eyepatch)] trait UserDefined { } impl UserDefined for i32 { } impl<'a, T> UserDefined for &'a T { } // e.g., `impl_drop!(Send, D_Send)` expands to: // ```rust // struct D_Send(T); // impl Drop for D_Send { fn drop(&mut self) { } } // ``` macro_rules! impl_drop { ($Bound:ident, $Id:ident) => { struct $Id(#[allow(unused_tuple_struct_fields)] T); unsafe impl <#[may_dangle] T: $Bound> Drop for $Id { fn drop(&mut self) { } } } } impl_drop!{Send, D_Send} impl_drop!{Sized, D_Sized} // See note below regarding Issue 24895 // impl_drop!{Copy, D_Copy} impl_drop!{Sync, D_Sync} impl_drop!{UserDefined, D_UserDefined} macro_rules! body { ($id:ident) => { { // `_d` and `d1` are assigned the *same* lifetime by region inference ... let (_d, d1); d1 = $id(1); // ... we store a reference to `d1` within `_d` ... _d = $id(&d1); // ... a *conservative* dropck will thus complain, because it // thinks Drop of _d could access the already dropped `d1`. } } } fn f_send() { body!(D_Send) } fn f_sized() { body!(D_Sized) } fn f_sync() { body!(D_Sync) } // Issue 24895: Copy: Clone implies `impl Drop for ...` can // access a user-defined clone() method, which causes this test case // to fail. // // If 24895 is resolved by removing the `Copy: Clone` relationship, // then this definition and the call below should be uncommented. If // it is resolved by deciding to keep the `Copy: Clone` relationship, // then this comment and the associated bits of code can all be // removed. // fn f_copy() { body!(D_Copy) } fn f_userdefined() { body!(D_UserDefined) } fn main() { f_send(); f_sized(); // See note above regarding Issue 24895. // f_copy(); f_sync(); f_userdefined(); }