rustc_public_bridge/
builder.rs1use rustc_hir::def::DefKind;
7use rustc_middle::mir;
8use rustc_middle::mir::visit::MutVisitor;
9use rustc_middle::ty::{self, TyCtxt};
10
11pub(crate) struct BodyBuilder<'tcx> {
13 tcx: TyCtxt<'tcx>,
14 instance: ty::Instance<'tcx>,
15}
16
17impl<'tcx> BodyBuilder<'tcx> {
18 pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
19 let instance = match instance.def {
20 ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args),
22 _ => instance,
23 };
24 BodyBuilder { tcx, instance }
25 }
26
27 pub(crate) fn build(mut self) -> mir::Body<'tcx> {
31 let body = self.tcx.instance_mir(self.instance.def).clone();
32 let mono_body = if !self.instance.args.is_empty()
33 || self.tcx.def_kind(self.instance.def_id()) != DefKind::AnonConst
37 {
38 let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions(
39 self.tcx,
40 ty::TypingEnv::fully_monomorphized(),
41 ty::EarlyBinder::bind(body),
42 );
43 self.visit_body(&mut mono_body);
44 mono_body
45 } else {
46 body
48 };
49
50 mono_body
51 }
52}
53
54impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
55 fn visit_const_operand(
56 &mut self,
57 constant: &mut mir::ConstOperand<'tcx>,
58 location: mir::Location,
59 ) {
60 let const_ = constant.const_;
61 let val = match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) {
62 Ok(v) => v,
63 Err(mir::interpret::ErrorHandled::Reported(..)) => return,
64 Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
65 unreachable!("Failed to evaluate instance constant: {:?}", const_)
66 }
67 };
68 let ty = constant.ty();
69 constant.const_ = mir::Const::Val(val, ty);
70 self.super_const_operand(constant, location);
71 }
72
73 fn tcx(&self) -> TyCtxt<'tcx> {
74 self.tcx
75 }
76}