blob: 555eefeb3a1f8722720151ae3eaf55f6fc498fae [file] [log] [blame]
// 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:Send>(T);
// impl<T:Send> Drop for D_Send<T> { fn drop(&mut self) { } }
// ```
macro_rules! impl_drop {
($Bound:ident, $Id:ident) => {
struct $Id<T: $Bound>(T);
unsafe impl <#[may_dangle] T: $Bound> Drop for $Id<T> {
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<T:Copy> 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();
}