use context::CrateContext;
use common::{fulfill_obligation, normalize_and_test_predicates,
type_is_sized};
-use glue;
+use glue::{self, DropGlueKind};
use llvm;
use meth;
use monomorphize::{self, Instance};
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TransItem<'tcx> {
- DropGlue(Ty<'tcx>),
+ DropGlue(DropGlueKind<'tcx>),
Fn(Instance<'tcx>),
Static(NodeId)
}
let def_id = ccx.tcx().map.local_def_id(node_id);
let ty = ccx.tcx().lookup_item_type(def_id).ty;
let ty = glue::get_drop_glue_type(ccx, ty);
- neighbors.push(TransItem::DropGlue(ty));
+ neighbors.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
recursion_depth_reset = None;
}
TransItem::Fn(instance) => {
&ty);
let ty = self.ccx.tcx().erase_regions(&ty);
let ty = glue::get_drop_glue_type(self.ccx, ty);
- self.output.push(TransItem::DropGlue(ty));
+ self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
}
self.super_lvalue(lvalue, context);
}
fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
- ty: ty::Ty<'tcx>,
- output: &mut Vec<TransItem<'tcx>>)
-{
+ dg: DropGlueKind<'tcx>,
+ output: &mut Vec<TransItem<'tcx>>) {
+ let ty = match dg {
+ DropGlueKind::Ty(ty) => ty,
+ DropGlueKind::TyContents(_) => {
+ // We already collected the neighbors of this item via the
+ // DropGlueKind::Ty variant.
+ return
+ }
+ };
+
debug!("find_drop_glue_neighbors: {}", type_to_string(ccx, ty));
// Make sure the exchange_free_fn() lang-item gets translated if
&Substs::empty());
output.push(trans_item);
}
+
+ // This type has a Drop implementation, we'll need the contents-only
+ // version of the glue too.
+ output.push(TransItem::DropGlue(DropGlueKind::TyContents(ty)));
}
// Finally add the types of nested values
let field_type = glue::get_drop_glue_type(ccx, field_type);
if glue::type_needs_drop(ccx.tcx(), field_type) {
- output.push(TransItem::DropGlue(field_type));
+ output.push(TransItem::DropGlue(DropGlueKind::Ty(field_type)));
}
}
}
for upvar_ty in &substs.upvar_tys {
let upvar_ty = glue::get_drop_glue_type(ccx, upvar_ty);
if glue::type_needs_drop(ccx.tcx(), upvar_ty) {
- output.push(TransItem::DropGlue(upvar_ty));
+ output.push(TransItem::DropGlue(DropGlueKind::Ty(upvar_ty)));
}
}
}
ty::TyArray(inner_type, _) => {
let inner_type = glue::get_drop_glue_type(ccx, inner_type);
if glue::type_needs_drop(ccx.tcx(), inner_type) {
- output.push(TransItem::DropGlue(inner_type));
+ output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type)));
}
}
ty::TyTuple(ref args) => {
for arg in args {
let arg = glue::get_drop_glue_type(ccx, arg);
if glue::type_needs_drop(ccx.tcx(), arg) {
- output.push(TransItem::DropGlue(arg));
+ output.push(TransItem::DropGlue(DropGlueKind::Ty(arg)));
}
}
}
self.ccx.tcx().map.local_def_id(item.id)));
let ty = glue::get_drop_glue_type(self.ccx, ty);
- self.output.push(TransItem::DropGlue(ty));
+ self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
}
}
}
let hir_map = &ccx.tcx().map;
return match *self {
- TransItem::DropGlue(t) => {
+ TransItem::DropGlue(dg) => {
let mut s = String::with_capacity(32);
- s.push_str("drop-glue ");
- push_unique_type_name(ccx, t, &mut s);
+ match dg {
+ DropGlueKind::Ty(_) => s.push_str("drop-glue "),
+ DropGlueKind::TyContents(_) => s.push_str("drop-glue-contents "),
+ };
+ push_unique_type_name(ccx, dg.ty(), &mut s);
s
}
TransItem::Fn(instance) => {
fn to_raw_string(&self) -> String {
match *self {
- TransItem::DropGlue(t) => {
- format!("DropGlue({})", t as *const _ as usize)
+ TransItem::DropGlue(dg) => {
+ format!("DropGlue({})", dg.ty() as *const _ as usize)
}
TransItem::Fn(instance) => {
format!("Fn({:?}, {})",
// Even if there is no dtor for t, there might be one deeper down and we
// might need to pass in the vtable ptr.
if !type_is_sized(tcx, t) {
- return t
+ return ccx.tcx().erase_regions(&t);
}
// FIXME (#22815): note that type_needs_drop conservatively
if llsize_of_alloc(ccx, llty) == 0 {
tcx.types.i8
} else {
- t
+ ccx.tcx().erase_regions(&t)
}
}
- _ => t
+ _ => ccx.tcx().erase_regions(&t)
}
}
}
impl<'tcx> DropGlueKind<'tcx> {
- fn ty(&self) -> Ty<'tcx> {
+ pub fn ty(&self) -> Ty<'tcx> {
match *self { DropGlueKind::Ty(t) | DropGlueKind::TyContents(t) => t }
}
- fn map_ty<F>(&self, mut f: F) -> DropGlueKind<'tcx> where F: FnMut(Ty<'tcx>) -> Ty<'tcx>
+ pub fn map_ty<F>(&self, mut f: F) -> DropGlueKind<'tcx> where F: FnMut(Ty<'tcx>) -> Ty<'tcx>
{
match *self {
DropGlueKind::Ty(t) => DropGlueKind::Ty(f(t)),
fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueKind<'tcx>)
-> Block<'blk, 'tcx> {
- let t = g.ty();
-
if collector::collecting_debug_information(bcx.ccx()) {
bcx.ccx()
- .record_translation_item_as_generated(TransItem::DropGlue(bcx.tcx()
- .erase_regions(&t)));
+ .record_translation_item_as_generated(TransItem::DropGlue(g));
}
+ let t = g.ty();
+
let skip_dtor = match g { DropGlueKind::Ty(_) => false, DropGlueKind::TyContents(_) => true };
// NB: v0 is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("make_drop_glue");
Some(instance.def)
}
- TransItem::DropGlue(t) => characteristic_def_id_of_type(t),
+ TransItem::DropGlue(dg) => characteristic_def_id_of_type(dg.ty()),
TransItem::Static(node_id) => Some(tcx.map.local_def_id(node_id)),
}
}
struct NonGenericWithDrop(i32);
//~ TRANS_ITEM drop-glue generic_drop_glue::NonGenericWithDrop[0]
+//~ TRANS_ITEM drop-glue-contents generic_drop_glue::NonGenericWithDrop[0]
impl Drop for NonGenericWithDrop {
+ //~ TRANS_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
fn drop(&mut self) {}
-//~ TRANS_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
}
//~ TRANS_ITEM fn generic_drop_glue::main[0]
fn main() {
//~ TRANS_ITEM drop-glue generic_drop_glue::StructWithDrop[0]<i8, char>
+ //~ TRANS_ITEM drop-glue-contents generic_drop_glue::StructWithDrop[0]<i8, char>
//~ TRANS_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
//~ TRANS_ITEM drop-glue generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
+ //~ TRANS_ITEM drop-glue-contents generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
//~ TRANS_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
//~ TRANS_ITEM drop-glue generic_drop_glue::EnumWithDrop[0]<i32, i64>
+ //~ TRANS_ITEM drop-glue-contents generic_drop_glue::EnumWithDrop[0]<i32, i64>
//~ TRANS_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
let _ = match EnumWithDrop::A::<i32, i64>(0) {
EnumWithDrop::A(x) => x,
};
//~ TRANS_ITEM drop-glue generic_drop_glue::EnumWithDrop[0]<f64, f32>
+ //~ TRANS_ITEM drop-glue-contents generic_drop_glue::EnumWithDrop[0]<f64, f32>
//~ TRANS_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
EnumWithDrop::A(x) => x,
#![deny(dead_code)]
//~ TRANS_ITEM drop-glue non_generic_drop_glue::StructWithDrop[0]
+//~ TRANS_ITEM drop-glue-contents non_generic_drop_glue::StructWithDrop[0]
struct StructWithDrop {
x: i32
}
}
//~ TRANS_ITEM drop-glue non_generic_drop_glue::EnumWithDrop[0]
+//~ TRANS_ITEM drop-glue-contents non_generic_drop_glue::EnumWithDrop[0]
enum EnumWithDrop {
A(i32)
}
//~ TRANS_ITEM drop-glue transitive_drop_glue::Intermediate[0]
struct Intermediate(Leaf);
//~ TRANS_ITEM drop-glue transitive_drop_glue::Leaf[0]
+//~ TRANS_ITEM drop-glue-contents transitive_drop_glue::Leaf[0]
struct Leaf;
impl Drop for Leaf {
fn drop(&mut self) {}
}
-//~ TRANS_ITEM drop-glue transitive_drop_glue::Root[0]
struct RootGen<T>(IntermediateGen<T>);
-//~ TRANS_ITEM drop-glue transitive_drop_glue::Root[0]
struct IntermediateGen<T>(LeafGen<T>);
-//~ TRANS_ITEM drop-glue transitive_drop_glue::Root[0]
struct LeafGen<T>(T);
impl<T> Drop for LeafGen<T> {
//~ TRANS_ITEM drop-glue transitive_drop_glue::RootGen[0]<u32>
//~ TRANS_ITEM drop-glue transitive_drop_glue::IntermediateGen[0]<u32>
//~ TRANS_ITEM drop-glue transitive_drop_glue::LeafGen[0]<u32>
+ //~ TRANS_ITEM drop-glue-contents transitive_drop_glue::LeafGen[0]<u32>
//~ TRANS_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
let _ = RootGen(IntermediateGen(LeafGen(0u32)));
//~ TRANS_ITEM drop-glue transitive_drop_glue::RootGen[0]<i16>
//~ TRANS_ITEM drop-glue transitive_drop_glue::IntermediateGen[0]<i16>
//~ TRANS_ITEM drop-glue transitive_drop_glue::LeafGen[0]<i16>
+ //~ TRANS_ITEM drop-glue-contents transitive_drop_glue::LeafGen[0]<i16>
//~ TRANS_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
let _ = RootGen(IntermediateGen(LeafGen(0i16)));
}
#![deny(dead_code)]
//~ TRANS_ITEM drop-glue tuple_drop_glue::Dropped[0]
+//~ TRANS_ITEM drop-glue-contents tuple_drop_glue::Dropped[0]
struct Dropped;
impl Drop for Dropped {
extern crate cgu_extern_drop_glue;
//~ TRANS_ITEM drop-glue cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[OnceODR] extern_drop_glue-mod1[OnceODR]
+//~ TRANS_ITEM drop-glue-contents cgu_extern_drop_glue::Struct[0] @@ extern_drop_glue[OnceODR] extern_drop_glue-mod1[OnceODR]
struct LocalStruct(cgu_extern_drop_glue::Struct);
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
}
-
#![crate_type="lib"]
//~ TRANS_ITEM drop-glue local_drop_glue::Struct[0] @@ local_drop_glue[OnceODR] local_drop_glue-mod1[OnceODR]
+//~ TRANS_ITEM drop-glue-contents local_drop_glue::Struct[0] @@ local_drop_glue[OnceODR] local_drop_glue-mod1[OnceODR]
struct Struct {
_a: u32
}