diff options
Diffstat (limited to 'src/test/ui/dropck')
-rw-r--r-- | src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr | 12 | ||||
-rw-r--r-- | src/test/ui/dropck/issue-24805-dropck-itemless.rs | 77 |
2 files changed, 89 insertions, 0 deletions
diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr index 49e55be1b..82169ee01 100644 --- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr @@ -8,6 +8,12 @@ LL | | // (unsafe to access self.1 due to #[may_dangle] on A) LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } LL | | } | |_^ + | + = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword +help: add `unsafe` to this trait implementation + | +LL | unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt<A, B> { + | ++++++ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:27:1 @@ -19,6 +25,12 @@ LL | | // (unsafe to access self.1 due to #[may_dangle] on 'a) LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } LL | | } | |_^ + | + = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword +help: add `unsafe` to this trait implementation + | +LL | unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { + | ++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/dropck/issue-24805-dropck-itemless.rs b/src/test/ui/dropck/issue-24805-dropck-itemless.rs new file mode 100644 index 000000000..45761b61c --- /dev/null +++ b/src/test/ui/dropck/issue-24805-dropck-itemless.rs @@ -0,0 +1,77 @@ +// 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>(#[allow(unused_tuple_struct_fields)] 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(); +} |