Skip to content

Commit 3e98ab5

Browse files
committed
rustc_trans: use the drop glue of T instead of Box<T> in Trait's vtable, be it &Trait or Box<Trait>.
1 parent c64d671 commit 3e98ab5

File tree

8 files changed

+90
-222
lines changed

8 files changed

+90
-222
lines changed

src/librustc_trans/trans/_match.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ fn bind_subslice_pat(bcx: Block,
660660
offset_right: uint) -> ValueRef {
661661
let _icx = push_ctxt("match::bind_subslice_pat");
662662
let vec_ty = node_id_type(bcx, pat_id);
663-
let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty)));
663+
let unit_ty = ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty));
664664
let vec_datum = match_datum(val, vec_ty);
665665
let (base, len) = vec_datum.get_vec_base_and_len(bcx);
666666

@@ -669,7 +669,7 @@ fn bind_subslice_pat(bcx: Block,
669669
let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
670670
let slice_ty = ty::mk_slice(bcx.tcx(),
671671
bcx.tcx().mk_region(ty::ReStatic),
672-
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
672+
ty::mt {ty: unit_ty, mutbl: ast::MutImmutable});
673673
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
674674
Store(bcx, slice_begin,
675675
GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));

src/librustc_trans/trans/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,10 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
702702
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
703703
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
704704
}
705+
ty::ty_vec(_, None) | ty::ty_str => {
706+
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
707+
cx = tvec::iter_vec_raw(cx, data_ptr, unit_ty, info.unwrap(), f);
708+
}
705709
ty::ty_tup(ref args) => {
706710
let repr = adt::represent_type(cx.ccx(), t);
707711
for (i, arg) in args.iter().enumerate() {

src/librustc_trans/trans/consts.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
314314
let info =
315315
expr::unsized_info(
316316
cx, k, e.id, ty, param_substs,
317-
|t| ty::mk_imm_rptr(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), t),
318317
|| const_get_elt(cx, llconst, &[abi::FAT_PTR_EXTRA as u32]));
319318

320319
let unsized_ty = ty::unsize_ty(cx.tcx(), ty, k, e.span);

src/librustc_trans/trans/context.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub struct LocalCrateContext<'tcx> {
102102
monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
103103
monomorphizing: RefCell<DefIdMap<uint>>,
104104
/// Cache generated vtables
105-
vtables: RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), ValueRef>>,
105+
vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
106106
/// Cache of constant strings,
107107
const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
108108

@@ -614,8 +614,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
614614
&self.local.monomorphizing
615615
}
616616

617-
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>),
618-
ValueRef>> {
617+
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
619618
&self.local.vtables
620619
}
621620

src/librustc_trans/trans/expr.rs

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -288,64 +288,47 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
288288
// Retrieve the information we are losing (making dynamic) in an unsizing
289289
// adjustment.
290290
//
291-
// When making a dtor, we need to do different things depending on the
292-
// ownership of the object.. mk_ty is a function for turning `unadjusted_ty`
293-
// into a type to be destructed. If we want to end up with a Box pointer,
294-
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
295-
// borrowed reference then it should be T -> &T.
296-
//
297291
// The `unadjusted_val` argument is a bit funny. It is intended
298292
// for use in an upcast, where the new vtable for an object will
299293
// be drived from the old one. Hence it is a pointer to the fat
300294
// pointer.
301-
pub fn unsized_info_bcx<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
302-
kind: &ty::UnsizeKind<'tcx>,
303-
id: ast::NodeId,
304-
unadjusted_ty: Ty<'tcx>,
305-
unadjusted_val: ValueRef, // see above (*)
306-
param_substs: &'tcx subst::Substs<'tcx>,
307-
mk_ty: F)
308-
-> ValueRef
309-
where F: FnOnce(Ty<'tcx>) -> Ty<'tcx>
310-
{
295+
pub fn unsized_info_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
296+
kind: &ty::UnsizeKind<'tcx>,
297+
id: ast::NodeId,
298+
unadjusted_ty: Ty<'tcx>,
299+
unadjusted_val: ValueRef, // see above (*)
300+
param_substs: &'tcx subst::Substs<'tcx>)
301+
-> ValueRef {
311302
unsized_info(
312303
bcx.ccx(),
313304
kind,
314305
id,
315306
unadjusted_ty,
316307
param_substs,
317-
mk_ty,
318308
|| Load(bcx, GEPi(bcx, unadjusted_val, &[0, abi::FAT_PTR_EXTRA])))
319309
}
320310

321311
// Same as `unsize_info_bcx`, but does not require a bcx -- instead it
322312
// takes an extra closure to compute the upcast vtable.
323-
pub fn unsized_info<'ccx, 'tcx, MK_TY, MK_UPCAST_VTABLE>(
313+
pub fn unsized_info<'ccx, 'tcx, MK_UPCAST_VTABLE>(
324314
ccx: &CrateContext<'ccx, 'tcx>,
325315
kind: &ty::UnsizeKind<'tcx>,
326316
id: ast::NodeId,
327317
unadjusted_ty: Ty<'tcx>,
328318
param_substs: &'tcx subst::Substs<'tcx>,
329-
mk_ty: MK_TY,
330319
mk_upcast_vtable: MK_UPCAST_VTABLE) // see notes above
331320
-> ValueRef
332-
where MK_TY: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
333-
MK_UPCAST_VTABLE: FnOnce() -> ValueRef,
321+
where MK_UPCAST_VTABLE: FnOnce() -> ValueRef
334322
{
335-
// FIXME(#19596) workaround: `|t| t` causes monomorphization recursion
336-
fn identity<T>(t: T) -> T { t }
337-
338323
debug!("unsized_info(kind={:?}, id={}, unadjusted_ty={})",
339324
kind, id, unadjusted_ty.repr(ccx.tcx()));
340325
match kind {
341326
&ty::UnsizeLength(len) => C_uint(ccx, len),
342327
&ty::UnsizeStruct(box ref k, tp_index) => match unadjusted_ty.sty {
343328
ty::ty_struct(_, ref substs) => {
344329
let ty_substs = substs.types.get_slice(subst::TypeSpace);
345-
// The dtor for a field treats it like a value, so mk_ty
346-
// should just be the identity function.
347330
unsized_info(ccx, k, id, ty_substs[tp_index], param_substs,
348-
identity, mk_upcast_vtable)
331+
mk_upcast_vtable)
349332
}
350333
_ => ccx.sess().bug(&format!("UnsizeStruct with bad sty: {}",
351334
unadjusted_ty.repr(ccx.tcx())))
@@ -359,8 +342,7 @@ pub fn unsized_info<'ccx, 'tcx, MK_TY, MK_UPCAST_VTABLE>(
359342
let trait_ref = monomorphize::apply_param_substs(ccx.tcx(),
360343
param_substs,
361344
&trait_ref);
362-
let box_ty = mk_ty(unadjusted_ty);
363-
consts::ptrcast(meth::get_vtable(ccx, box_ty, trait_ref, param_substs),
345+
consts::ptrcast(meth::get_vtable(ccx, trait_ref, param_substs),
364346
Type::vtable_ptr(ccx))
365347
}
366348
&ty::UnsizeUpcast(_) => {
@@ -498,8 +480,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
498480
let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
499481
debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx()));
500482

501-
let info = unsized_info_bcx(bcx, k, expr.id, datum_ty, datum.val, bcx.fcx.param_substs,
502-
|t| ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), t));
483+
let info = unsized_info_bcx(bcx, k, expr.id, datum_ty, datum.val, bcx.fcx.param_substs);
503484

504485
// Arrange cleanup
505486
let lval = unpack_datum!(bcx, datum.to_lvalue_datum(bcx, "into_fat_ptr", expr.id));
@@ -590,8 +571,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
590571
let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
591572
bcx = datum.store_to(bcx, base);
592573

593-
let info = unsized_info_bcx(bcx, k, expr.id, unboxed_ty, base, bcx.fcx.param_substs,
594-
|t| ty::mk_uniq(tcx, t));
574+
let info = unsized_info_bcx(bcx, k, expr.id, unboxed_ty, base, bcx.fcx.param_substs);
595575
Store(bcx, info, get_len(bcx, scratch.val));
596576

597577
DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -888,10 +868,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
888868
}
889869
};
890870

891-
let vt =
892-
tvec::vec_types(bcx,
893-
ty::sequence_element_type(bcx.tcx(),
894-
base_datum.ty));
871+
let unit_ty = ty::sequence_element_type(bcx.tcx(), base_datum.ty);
895872

896873
let (base, len) = base_datum.get_vec_base_and_len(bcx);
897874

@@ -916,8 +893,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
916893
len)
917894
});
918895
let elt = InBoundsGEP(bcx, base, &[ix_val]);
919-
let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
920-
Datum::new(elt, vt.unit_ty, LvalueExpr)
896+
let elt = PointerCast(bcx, elt, type_of::type_of(ccx, unit_ty).ptr_to());
897+
Datum::new(elt, unit_ty, LvalueExpr)
921898
}
922899
};
923900

src/librustc_trans/trans/glue.rs

Lines changed: 32 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use trans::datum;
3232
use trans::debuginfo::DebugLoc;
3333
use trans::expr;
3434
use trans::machine::*;
35-
use trans::tvec;
3635
use trans::type_::Type;
3736
use trans::type_of::{self, type_of, sizing_type_of, align_of};
3837
use middle::ty::{self, Ty};
@@ -386,51 +385,34 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
386385
let _icx = push_ctxt("make_drop_glue");
387386
match t.sty {
388387
ty::ty_uniq(content_ty) => {
389-
match content_ty.sty {
390-
ty::ty_vec(ty, None) => {
391-
tvec::make_drop_glue_unboxed(bcx, v0, ty, true)
392-
}
393-
ty::ty_str => {
394-
let unit_ty = ty::sequence_element_type(bcx.tcx(), content_ty);
395-
tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true)
396-
}
397-
ty::ty_trait(..) => {
398-
let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
399-
// Only drop the value when it is non-null
400-
let concrete_ptr = Load(bcx, lluniquevalue);
401-
with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| {
402-
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
403-
let dtor = Load(bcx, dtor_ptr);
404-
Call(bcx,
405-
dtor,
406-
&[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
407-
None,
408-
DebugLoc::None);
409-
bcx
410-
})
411-
}
412-
ty::ty_struct(..) if !type_is_sized(bcx.tcx(), content_ty) => {
413-
let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
414-
let llbox = Load(bcx, llval);
415-
let not_null = IsNotNull(bcx, llbox);
416-
with_cond(bcx, not_null, |bcx| {
417-
let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
418-
let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
419-
let info = Load(bcx, info);
420-
let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
388+
if !type_is_sized(bcx.tcx(), content_ty) {
389+
let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
390+
let llbox = Load(bcx, llval);
391+
let not_null = IsNotNull(bcx, llbox);
392+
with_cond(bcx, not_null, |bcx| {
393+
let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
394+
let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
395+
let info = Load(bcx, info);
396+
let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
397+
398+
// `Box<ZeroSizeType>` does not allocate.
399+
let needs_free = ICmp(bcx,
400+
llvm::IntNE,
401+
llsize,
402+
C_uint(bcx.ccx(), 0u64),
403+
DebugLoc::None);
404+
with_cond(bcx, needs_free, |bcx| {
421405
trans_exchange_free_dyn(bcx, llbox, llsize, llalign, DebugLoc::None)
422406
})
423-
}
424-
_ => {
425-
assert!(type_is_sized(bcx.tcx(), content_ty));
426-
let llval = v0;
427-
let llbox = Load(bcx, llval);
428-
let not_null = IsNotNull(bcx, llbox);
429-
with_cond(bcx, not_null, |bcx| {
430-
let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
431-
trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
432-
})
433-
}
407+
})
408+
} else {
409+
let llval = v0;
410+
let llbox = Load(bcx, llval);
411+
let not_null = IsNotNull(bcx, llbox);
412+
with_cond(bcx, not_null, |bcx| {
413+
let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
414+
trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
415+
})
434416
}
435417
}
436418
ty::ty_struct(did, substs) | ty::ty_enum(did, substs) => {
@@ -462,34 +444,19 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
462444
}
463445
}
464446
}
465-
ty::ty_closure(..) => {
466-
iter_structural_ty(bcx,
467-
v0,
468-
t,
469-
|bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
470-
}
471447
ty::ty_trait(..) => {
472-
// No need to do a null check here (as opposed to the Box<trait case
473-
// above), because this happens for a trait field in an unsized
474-
// struct. If anything is null, it is the whole struct and we won't
475-
// get here.
476-
let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
477-
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
478-
let dtor = Load(bcx, dtor_ptr);
448+
let data_ptr = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
449+
let vtable_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
450+
let dtor = Load(bcx, vtable_ptr);
479451
Call(bcx,
480452
dtor,
481-
&[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
453+
&[PointerCast(bcx, Load(bcx, data_ptr), Type::i8p(bcx.ccx()))],
482454
None,
483455
DebugLoc::None);
484456
bcx
485-
},
486-
ty::ty_vec(_, None) | ty::ty_str => {
487-
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
488-
tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, false)
489-
},
457+
}
490458
_ => {
491-
assert!(type_is_sized(bcx.tcx(), t));
492-
if bcx.fcx.type_needs_drop(t) && ty::type_is_structural(t) {
459+
if bcx.fcx.type_needs_drop(t) {
493460
iter_structural_ty(bcx,
494461
v0,
495462
t,

src/librustc_trans/trans/meth.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -680,25 +680,19 @@ pub fn trans_object_shim<'a, 'tcx>(
680680
///
681681
/// The `trait_ref` encodes the erased self type. Hence if we are
682682
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
683-
/// `trait_ref` would map `T:Trait`, but `box_ty` would be
684-
/// `Foo<T>`. This `box_ty` is primarily used to encode the destructor.
685-
/// This will hopefully change now that DST is underway.
683+
/// `trait_ref` would map `T:Trait`.
686684
pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
687-
box_ty: Ty<'tcx>,
688685
trait_ref: ty::PolyTraitRef<'tcx>,
689686
param_substs: &'tcx subst::Substs<'tcx>)
690687
-> ValueRef
691688
{
692689
let tcx = ccx.tcx();
693690
let _icx = push_ctxt("meth::get_vtable");
694691

695-
debug!("get_vtable(box_ty={}, trait_ref={})",
696-
box_ty.repr(tcx),
697-
trait_ref.repr(tcx));
692+
debug!("get_vtable(trait_ref={})", trait_ref.repr(tcx));
698693

699694
// Check the cache.
700-
let cache_key = (box_ty, trait_ref.clone());
701-
match ccx.vtables().borrow().get(&cache_key) {
695+
match ccx.vtables().borrow().get(&trait_ref) {
702696
Some(&val) => { return val }
703697
None => { }
704698
}
@@ -755,15 +749,15 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
755749

756750
let components: Vec<_> = vec![
757751
// Generate a destructor for the vtable.
758-
glue::get_drop_glue(ccx, box_ty),
752+
glue::get_drop_glue(ccx, trait_ref.self_ty()),
759753
C_uint(ccx, size),
760754
C_uint(ccx, align)
761755
].into_iter().chain(methods).collect();
762756

763757
let vtable = consts::addr_of(ccx, C_struct(ccx, &components, false),
764758
"vtable", trait_ref.def_id().node);
765759

766-
ccx.vtables().borrow_mut().insert(cache_key, vtable);
760+
ccx.vtables().borrow_mut().insert(trait_ref, vtable);
767761
vtable
768762
}
769763

@@ -842,16 +836,15 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
842836
debug!("trans_trait_cast: trait_ref={}",
843837
trait_ref.repr(bcx.tcx()));
844838

845-
let datum_ty = datum.ty;
846-
let llbox_ty = type_of(bcx.ccx(), datum_ty);
839+
let llty = type_of(bcx.ccx(), datum.ty);
847840

848841
// Store the pointer into the first half of pair.
849842
let llboxdest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_ADDR]);
850-
let llboxdest = PointerCast(bcx, llboxdest, llbox_ty.ptr_to());
843+
let llboxdest = PointerCast(bcx, llboxdest, llty.ptr_to());
851844
bcx = datum.store_to(bcx, llboxdest);
852845

853846
// Store the vtable into the second half of pair.
854-
let vtable = get_vtable(bcx.ccx(), datum_ty, trait_ref, bcx.fcx.param_substs);
847+
let vtable = get_vtable(bcx.ccx(), trait_ref, bcx.fcx.param_substs);
855848
let llvtabledest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_EXTRA]);
856849
let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
857850
Store(bcx, vtable, llvtabledest);

0 commit comments

Comments
 (0)