]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/interpret/terminator/drop.rs
Address stylistic review comments and rebase fallout
[rust.git] / src / librustc_mir / interpret / terminator / drop.rs
1 use rustc::mir::BasicBlock;
2 use rustc::ty::{self, Ty};
3 use syntax::codemap::Span;
4
5 use rustc::mir::interpret::{EvalResult, Value};
6 use interpret::{Machine, ValTy, EvalContext, Place, PlaceExtra};
7
8 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
9     pub(crate) fn drop_place(
10         &mut self,
11         place: Place,
12         instance: ty::Instance<'tcx>,
13         ty: Ty<'tcx>,
14         span: Span,
15         target: BasicBlock,
16     ) -> EvalResult<'tcx> {
17         trace!("drop_place: {:#?}", place);
18         // We take the address of the object.  This may well be unaligned, which is fine for us here.
19         // However, unaligned accesses will probably make the actual drop implementation fail -- a problem shared
20         // by rustc.
21         let val = match self.force_allocation(place)? {
22             Place::Ptr {
23                 ptr,
24                 align: _,
25                 extra: PlaceExtra::Vtable(vtable),
26             } => ptr.to_value_with_vtable(vtable),
27             Place::Ptr {
28                 ptr,
29                 align: _,
30                 extra: PlaceExtra::Length(len),
31             } => ptr.to_value_with_len(len, self.tcx.tcx),
32             Place::Ptr {
33                 ptr,
34                 align: _,
35                 extra: PlaceExtra::None,
36             } => Value::Scalar(ptr),
37             _ => bug!("force_allocation broken"),
38         };
39         self.drop(val, instance, ty, span, target)
40     }
41
42     fn drop(
43         &mut self,
44         arg: Value,
45         instance: ty::Instance<'tcx>,
46         ty: Ty<'tcx>,
47         span: Span,
48         target: BasicBlock,
49     ) -> EvalResult<'tcx> {
50         trace!("drop: {:#?}, {:?}, {:?}", arg, ty.sty, instance.def);
51
52         let instance = match ty.sty {
53             ty::TyDynamic(..) => {
54                 if let Value::ScalarPair(_, vtable) = arg {
55                     self.read_drop_type_from_vtable(vtable.unwrap_or_err()?.to_ptr()?)?
56                 } else {
57                     bug!("expected fat ptr, got {:?}", arg);
58                 }
59             }
60             _ => instance,
61         };
62
63         // the drop function expects a reference to the value
64         let valty = ValTy {
65             value: arg,
66             ty: self.tcx.mk_mut_ptr(ty),
67         };
68
69         let fn_sig = self.tcx.fn_sig(instance.def_id()).skip_binder().clone();
70
71         self.eval_fn_call(
72             instance,
73             Some((Place::undef(), target)),
74             &[valty],
75             span,
76             fn_sig,
77         )
78     }
79 }