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