Call destructors when dyn* object goes out of scope
This commit is contained in:
parent
549c105bb3
commit
c5441acf67
8 changed files with 59 additions and 18 deletions
|
@ -86,6 +86,7 @@ fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'
|
|||
/// The `trait_ref` encodes the erased self type. Hence if we are
|
||||
/// making an object `Foo<dyn Trait>` from a value of type `Foo<T>`, then
|
||||
/// `trait_ref` would map `T: Trait`.
|
||||
#[instrument(level = "debug", skip(cx))]
|
||||
pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||
cx: &Cx,
|
||||
ty: Ty<'tcx>,
|
||||
|
@ -93,8 +94,6 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
|
|||
) -> Cx::Value {
|
||||
let tcx = cx.tcx();
|
||||
|
||||
debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref);
|
||||
|
||||
// Check the cache.
|
||||
if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
|
||||
return val;
|
||||
|
|
|
@ -16,7 +16,7 @@ use rustc_index::vec::Idx;
|
|||
use rustc_middle::mir::{self, AssertKind, SwitchTargets};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TypeVisitable, TraitObjectRepresentation};
|
||||
use rustc_middle::ty::{self, Instance, TraitObjectRepresentation, Ty, TypeVisitable};
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_symbol_mangling::typeid::typeid_for_fnabi;
|
||||
|
@ -451,7 +451,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
|
||||
//
|
||||
// SO THEN WE CAN USE THE ABOVE CODE.
|
||||
todo!()
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
|
||||
substs: drop_fn.substs,
|
||||
};
|
||||
debug!("ty = {:?}", ty);
|
||||
debug!("drop_fn = {:?}", drop_fn);
|
||||
debug!("args = {:?}", args);
|
||||
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
let data = args[0];
|
||||
let data_ty = bx.cx().backend_type(place.layout);
|
||||
let vtable_ptr =
|
||||
bx.gep(data_ty, data, &[bx.cx().const_i32(0), bx.cx().const_i32(1)]);
|
||||
let vtable = bx.load(bx.type_i8p(), vtable_ptr, abi::Align::ONE);
|
||||
// Truncate vtable off of args list
|
||||
args = &args[..1];
|
||||
debug!("args' = {:?}", args);
|
||||
(
|
||||
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
|
||||
.get_fn(&mut bx, vtable, ty, &fn_abi),
|
||||
fn_abi,
|
||||
)
|
||||
}
|
||||
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ use super::{FunctionCx, LocalRef};
|
|||
|
||||
use crate::base;
|
||||
use crate::common::{self, IntPredicate};
|
||||
use crate::meth::get_vtable;
|
||||
use crate::traits::*;
|
||||
use crate::MemFlags;
|
||||
|
||||
|
@ -11,6 +12,7 @@ use rustc_middle::mir;
|
|||
use rustc_middle::mir::Operand;
|
||||
use rustc_middle::ty::cast::{CastTy, IntTy};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
|
||||
use rustc_middle::ty::TraitObjectRepresentation;
|
||||
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
|
||||
use rustc_span::source_map::{Span, DUMMY_SP};
|
||||
|
||||
|
@ -271,14 +273,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bug!("unexpected non-pair operand");
|
||||
}
|
||||
}
|
||||
#[allow(unreachable_code, unused)] // FIXME: remove this
|
||||
mir::CastKind::DynStar => {
|
||||
let data = match operand.val {
|
||||
OperandValue::Ref(_, _, _) => todo!(),
|
||||
OperandValue::Immediate(_) => todo!(),
|
||||
OperandValue::Immediate(v) => v,
|
||||
OperandValue::Pair(_, _) => todo!(),
|
||||
};
|
||||
let vtable = todo!();
|
||||
// FIXME: find the real vtable!
|
||||
let trait_ref = if let ty::Dynamic(data, _, TraitObjectRepresentation::Sized) = cast.ty.kind() {
|
||||
data.principal()
|
||||
} else {
|
||||
bug!("Only valid to do a DynStar cast into a DynStar type")
|
||||
};
|
||||
let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref);
|
||||
OperandValue::Pair(data, vtable)
|
||||
}
|
||||
mir::CastKind::Pointer(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue