Auto merge of #53288 - RalfJung:dropck, r=nikomatsakis
unions are not always trivially dropable Fixes #52786 r? @nikomatsakis
This commit is contained in:
commit
8dad6be9ad
@ -242,16 +242,14 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
|
|||||||
.all(|t| trivial_dropck_outlives(tcx, t)),
|
.all(|t| trivial_dropck_outlives(tcx, t)),
|
||||||
|
|
||||||
ty::TyAdt(def, _) => {
|
ty::TyAdt(def, _) => {
|
||||||
if def.is_union() {
|
if Some(def.did) == tcx.lang_items().manually_drop() {
|
||||||
// Unions never have a dtor.
|
|
||||||
true
|
|
||||||
} else if Some(def.did) == tcx.lang_items().manually_drop() {
|
|
||||||
// `ManuallyDrop` never has a dtor.
|
// `ManuallyDrop` never has a dtor.
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
// Other types might. Moreover, PhantomData doesn't
|
// Other types might. Moreover, PhantomData doesn't
|
||||||
// have a dtor, but it is considered to own its
|
// have a dtor, but it is considered to own its
|
||||||
// content, so it is non-trivial.
|
// content, so it is non-trivial. Unions can have `impl Drop`,
|
||||||
|
// and hence are non-trivial as well.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
src/test/ui/dropck/dropck-union.nll.stderr
Normal file
16
src/test/ui/dropck/dropck-union.nll.stderr
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
error[E0597]: `v` does not live long enough
|
||||||
|
--> $DIR/dropck-union.rs:49: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`.
|
50
src/test/ui/dropck/dropck-union.rs
Normal file
50
src/test/ui/dropck/dropck-union.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![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
|
||||||
|
}
|
13
src/test/ui/dropck/dropck-union.stderr
Normal file
13
src/test/ui/dropck/dropck-union.stderr
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
error[E0597]: `v` does not live long enough
|
||||||
|
--> $DIR/dropck-union.rs:49: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`.
|
Loading…
Reference in New Issue
Block a user