unions are not always trivially dropable

Fixes #52786
This commit is contained in:
Ralf Jung 2018-08-12 18:58:08 +02:00
parent 0aa8d03202
commit 376a6b2663
4 changed files with 72 additions and 5 deletions

View file

@ -0,0 +1,16 @@
error[E0597]: `v` does not live long enough
--> $DIR/dropck-union.rs:39:18
|
LL | v.0.set(Some(&v)); //~ ERROR: `v` does not live long enough
| ^^ borrowed value does not live long enough
LL | }
| -
| |
| `v` dropped here while still borrowed
| borrow later used here, when `v` is dropped
|
= note: values in a scope are dropped in the opposite order they are defined
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.

View file

@ -0,0 +1,40 @@
#![feature(untagged_unions)]
use std::cell::Cell;
use std::ops::Deref;
use std::mem::ManuallyDrop;
union Wrap<T> { x: ManuallyDrop<T> }
impl<T> Drop for Wrap<T> {
fn drop(&mut self) {
unsafe { std::ptr::drop_in_place(&mut *self.x as *mut T); }
}
}
impl<T> Wrap<T> {
fn new(x: T) -> Self {
Wrap { x: ManuallyDrop::new(x) }
}
}
impl<T> Deref for Wrap<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe {
&self.x
}
}
}
struct C<'a>(Cell<Option<&'a C<'a>>>);
impl<'a> Drop for C<'a> {
fn drop(&mut self) {}
}
fn main() {
let v : Wrap<C> = Wrap::new(C(Cell::new(None)));
v.0.set(Some(&v)); //~ ERROR: `v` does not live long enough
}

View file

@ -0,0 +1,13 @@
error[E0597]: `v` does not live long enough
--> $DIR/dropck-union.rs:39:19
|
LL | v.0.set(Some(&v)); //~ ERROR: `v` does not live long enough
| ^ borrowed value does not live long enough
LL | }
| - `v` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.