//! Logic required to produce a monomorphic body.
//!
//! We retrieve and monomorphize the rustc body representation, i.e., we generate a
//! monomorphic body using internal representation.

use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::ty::{self, TyCtxt};

/// Builds a monomorphic body for a given instance.
pub(crate) struct BodyBuilder<'tcx> {
    tcx: TyCtxt<'tcx>,
    instance: ty::Instance<'tcx>,
}

impl<'tcx> BodyBuilder<'tcx> {
    pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
        let instance = match instance.def {
            // To get the fallback body of an intrinsic, we need to convert it to an item.
            ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args),
            _ => instance,
        };
        BodyBuilder { tcx, instance }
    }

    /// Build a monomorphic body for a given instance based on the MIR body.
    ///
    /// All constants are also evaluated.
    pub(crate) fn build(mut self) -> mir::Body<'tcx> {
        let body = self.tcx.instance_mir(self.instance.def).clone();
        let mono_body = if !self.instance.args.is_empty()
            // Without the `generic_const_exprs` feature gate, anon consts in signatures do not
            // get generic parameters. Which is wrong, but also not a problem without
            // generic_const_exprs
            || self.tcx.def_kind(self.instance.def_id()) != DefKind::AnonConst
        {
            let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions(
                self.tcx,
                ty::TypingEnv::fully_monomorphized(),
                ty::EarlyBinder::bind(body),
            );
            self.visit_body(&mut mono_body);
            mono_body
        } else {
            // Already monomorphic.
            body
        };

        mono_body
    }
}

impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
    fn visit_const_operand(
        &mut self,
        constant: &mut mir::ConstOperand<'tcx>,
        location: mir::Location,
    ) {
        let const_ = constant.const_;
        let val = match const_.eval(self.tcx, ty::TypingEnv::fully_monomorphized(), constant.span) {
            Ok(v) => v,
            Err(mir::interpret::ErrorHandled::Reported(..)) => return,
            Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
                unreachable!("Failed to evaluate instance constant: {:?}", const_)
            }
        };
        let ty = constant.ty();
        constant.const_ = mir::Const::Val(val, ty);
        self.super_const_operand(constant, location);
    }

    fn tcx(&self) -> TyCtxt<'tcx> {
        self.tcx
    }
}
