Let the translation item collector make a distinction between drop-glue kinds

This commit is contained in:
Michael Woerister 2016-04-21 15:36:57 -04:00
parent ea6b3ddee9
commit c61f22932d
9 changed files with 55 additions and 32 deletions

View File

@ -211,7 +211,7 @@ use base::{custom_coerce_unsize_info, llvm_linkage_by_name};
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};
@ -227,7 +227,7 @@ pub enum TransItemCollectionMode {
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum TransItem<'tcx> {
DropGlue(Ty<'tcx>),
DropGlue(DropGlueKind<'tcx>),
Fn(Instance<'tcx>),
Static(NodeId)
}
@ -326,7 +326,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
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) => {
@ -485,7 +485,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
&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);
@ -575,9 +575,17 @@ fn can_have_local_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
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
@ -634,6 +642,10 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
&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
@ -661,7 +673,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
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)));
}
}
}
@ -669,7 +681,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
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)));
}
}
}
@ -677,14 +689,14 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
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)));
}
}
}
@ -1000,7 +1012,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
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)));
}
}
}
@ -1413,10 +1425,13 @@ impl<'tcx> TransItem<'tcx> {
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) => {
@ -1442,8 +1457,8 @@ impl<'tcx> TransItem<'tcx> {
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({:?}, {})",

View File

@ -98,7 +98,7 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// 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
@ -121,10 +121,10 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
if llsize_of_alloc(ccx, llty) == 0 {
tcx.types.i8
} else {
t
ccx.tcx().erase_regions(&t)
}
}
_ => t
_ => ccx.tcx().erase_regions(&t)
}
}
@ -215,11 +215,11 @@ pub enum DropGlueKind<'tcx> {
}
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)),
@ -487,14 +487,13 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
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");

View File

@ -304,7 +304,7 @@ fn characteristic_def_id_of_trans_item<'tcx>(tcx: &TyCtxt<'tcx>,
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)),
}
}

View File

@ -46,19 +46,22 @@ struct NonGenericNoDrop(i32);
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;
@ -71,6 +74,7 @@ fn main() {
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,
@ -78,6 +82,7 @@ fn main() {
};
//~ 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,

View File

@ -14,6 +14,7 @@
#![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
}
@ -28,6 +29,7 @@ struct StructNoDrop {
}
//~ 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)
}

View File

@ -18,6 +18,7 @@ struct Root(Intermediate);
//~ 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 {
@ -25,11 +26,8 @@ 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> {
@ -44,12 +42,14 @@ fn main() {
//~ 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)));
}

View File

@ -14,6 +14,7 @@
#![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 {

View File

@ -18,6 +18,7 @@
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);
@ -40,4 +41,3 @@ mod mod1 {
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
}

View File

@ -15,6 +15,7 @@
#![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
}