providers.mir_shims = make_shim;
}
-fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
+fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx BodyCache<'tcx> {
debug!("make_shim({:?})", instance);
let mut result = match instance {
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
}
};
- debug!("make_shim({:?}) = untransformed {:?}", instance, result);
+ debug!("make_shim({:?}) = untransformed {:?}", instance, result.body());
run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&add_call_guards::CriticalCallEdges,
]);
- // The `ensure_predecessors_cache::EnsurePredecessorsCache` MirPass wasn't used in the
- // `run_passes` above because the above pass is not always guaranteed to run. There can be
- // instances where, e.g. a `MirPhase::Validated` pass has already been run on a `Body` by the
- // time it arrived at this line, and so the above `run_passes` call will NOT run any of the
- // passes (They do not run if a same or later pass has already been executed on a `Body`).
- // Adding the ensure pass during the `run_passes` for `MirPhase::Validated` would not
- // help because the predecessors cache would be invalidated between that pass and this call.
- // Having the single ensure outside of the `run_passes` list here guarantees that anyone
- // using this `Body` could call `Body::unwrap_predecessors()` without worrying about a panic.
- result.ensure_predecessors();
-
- debug!("make_shim({:?}) = {:?}", instance, result);
+ debug!("make_shim({:?}) = {:?}", instance, result.body());
+ result.ensure_predecessors();
tcx.arena.alloc(result)
}
.collect()
}
-fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) -> Body<'tcx> {
+fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) -> BodyCache<'tcx> {
debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
// Check if this is a generator, if so, return the drop glue for it
sig.inputs().len(),
span);
+ let mut body_cache = BodyCache::new(body);
+
if let Some(..) = ty {
// The first argument (index 0), but add 1 for the return value.
let dropee_ptr = Place::from(Local::new(1+0));
if tcx.sess.opts.debugging_opts.mir_emit_retag {
// Function arguments should be retagged, and we make this one raw.
- body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
+ body_cache.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
source_info,
kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())),
});
let patch = {
let param_env = tcx.param_env(def_id).with_reveal_all();
let mut elaborator = DropShimElaborator {
- body: &body,
- patch: MirPatch::new(&body),
+ body: body_cache.body(),
+ patch: MirPatch::new(body_cache.body()),
tcx,
param_env
};
);
elaborator.patch
};
- patch.apply(&mut body);
+ patch.apply(&mut body_cache);
}
- body
+ body_cache
}
fn new_body<'tcx>(
}
/// Builds a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`.
-fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
+fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> BodyCache<'tcx> {
debug!("build_clone_shim(def_id={:?})", def_id);
let param_env = tcx.param_env(def_id);
}
};
- builder.into_mir()
+ BodyCache::new(builder.into_mir())
}
struct CloneShimBuilder<'tcx> {
rcvr_adjustment: Adjustment,
call_kind: CallKind,
untuple_args: Option<&[Ty<'tcx>]>,
-) -> Body<'tcx> {
+) -> BodyCache<'tcx> {
debug!("build_call_shim(def_id={:?}, rcvr_adjustment={:?}, \
call_kind={:?}, untuple_args={:?})",
def_id, rcvr_adjustment, call_kind, untuple_args);
if let Abi::RustCall = sig.abi {
body.spread_arg = Some(Local::new(sig.inputs().len()));
}
- body
+ BodyCache::new(body)
}
-pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
+pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyCache<'_> {
debug_assert!(tcx.is_constructor(ctor_id));
let span = tcx.hir().span_if_local(ctor_id)
sig.inputs().len(),
span,
);
- body.ensure_predecessors();
crate::util::dump_mir(
tcx,
|_, _| Ok(()),
);
- tcx.arena.alloc(body)
+ let mut body_cache = BodyCache::new(body);
+ body_cache.ensure_predecessors();
+ tcx.arena.alloc(body_cache)
}