use rustc::hir::def_id::DefId;
use rustc::mir::*;
use rustc::ty::TyCtxt;

use crate::transform::{MirPass, MirSource};
use crate::util::patch::MirPatch;
use crate::util;

// This pass moves values being dropped that are within a packed
// struct to a separate local before dropping them, to ensure that
// they are dropped from an aligned address.
//
// For example, if we have something like
// ```Rust
//     #[repr(packed)]
//     struct Foo {
//         dealign: u8,
//         data: Vec<u8>
//     }
//
//     let foo = ...;
// ```
//
// We want to call `drop_in_place::<Vec<u8>>` on `data` from an aligned
// address. This means we can't simply drop `foo.data` directly, because
// its address is not aligned.
//
// Instead, we move `foo.data` to a local and drop that:
// ```
//     storage.live(drop_temp)
//     drop_temp = foo.data;
//     drop(drop_temp) -> next
// next:
//     storage.dead(drop_temp)
// ```
//
// The storage instructions are required to avoid stack space
// blowup.

pub struct AddMovesForPackedDrops;

impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
        debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body.span);
        add_moves_for_packed_drops(tcx, body, src.def_id());
    }
}

pub fn add_moves_for_packed_drops<'tcx>(
    tcx: TyCtxt<'tcx>, body: &mut BodyAndCache<'tcx>, def_id: DefId
) {
    let patch = add_moves_for_packed_drops_patch(tcx, body, def_id);
    patch.apply(body);
}

fn add_moves_for_packed_drops_patch<'tcx>(
    tcx: TyCtxt<'tcx>,
    body: &Body<'tcx>,
    def_id: DefId,
) -> MirPatch<'tcx> {
    let mut patch = MirPatch::new(body);
    let param_env = tcx.param_env(def_id);

    for (bb, data) in body.basic_blocks().iter_enumerated() {
        let loc = Location { block: bb, statement_index: data.statements.len() };
        let terminator = data.terminator();

        match terminator.kind {
            TerminatorKind::Drop { ref location, .. }
                if util::is_disaligned(tcx, body, param_env, location) =>
            {
                add_move_for_packed_drop(tcx, body, &mut patch, terminator,
                                         loc, data.is_cleanup);
            }
            TerminatorKind::DropAndReplace { .. } => {
                span_bug!(terminator.source_info.span,
                          "replace in AddMovesForPackedDrops");
            }
            _ => {}
        }
    }

    patch
}

fn add_move_for_packed_drop<'tcx>(
    tcx: TyCtxt<'tcx>,
    body: &Body<'tcx>,
    patch: &mut MirPatch<'tcx>,
    terminator: &Terminator<'tcx>,
    loc: Location,
    is_cleanup: bool,
) {
    debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc);
    let (location, target, unwind) = match terminator.kind {
        TerminatorKind::Drop { ref location, target, unwind } =>
            (location, target, unwind),
        _ => unreachable!()
    };

    let source_info = terminator.source_info;
    let ty = location.ty(body, tcx).ty;
    let temp = patch.new_temp(ty, terminator.source_info.span);

    let storage_dead_block = patch.new_block(BasicBlockData {
        statements: vec![Statement {
            source_info, kind: StatementKind::StorageDead(temp)
        }],
        terminator: Some(Terminator {
            source_info, kind: TerminatorKind::Goto { target }
        }),
        is_cleanup
    });

    patch.add_statement(
        loc, StatementKind::StorageLive(temp));
    patch.add_assign(loc, Place::from(temp),
                     Rvalue::Use(Operand::Move(location.clone())));
    patch.patch_terminator(loc.block, TerminatorKind::Drop {
        location: Place::from(temp),
        target: storage_dead_block,
        unwind
    });
}
