use crate::build;
use crate::build::scope::DropKind;
use crate::hair::cx::Cx;
use crate::hair::{LintLevel, BindingMode, PatternKind};
use crate::transform::MirSource;
use crate::util as mir_util;
use rustc::hir;
use rustc::hir::Node;
use rustc::hir::def_id::DefId;
use rustc::middle::region;
use rustc::mir::*;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::HirIdMap;
use rustc_target::spec::PanicStrategy;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use std::u32;
use rustc_target::spec::abi::Abi;
use syntax::attr::{self, UnwindAttr};
use syntax::symbol::kw;
use syntax_pos::Span;

use super::lints;

/// Construct the MIR for a given `DefId`.
pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
    let id = tcx.hir().as_local_hir_id(def_id).unwrap();

    // Figure out what primary body this item has.
    let (body_id, return_ty_span) = match tcx.hir().get(id) {
        Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
        | Node::Item(hir::Item { node: hir::ItemKind::Fn(decl, _, _, body_id), .. })
        | Node::ImplItem(
            hir::ImplItem {
                node: hir::ImplItemKind::Method(hir::MethodSig { decl, .. }, body_id),
                ..
            }
        )
        | Node::TraitItem(
            hir::TraitItem {
                node: hir::TraitItemKind::Method(
                    hir::MethodSig { decl, .. },
                    hir::TraitMethod::Provided(body_id),
                ),
                ..
            }
        ) => {
            (*body_id, decl.output.span())
        }
        Node::Item(hir::Item { node: hir::ItemKind::Static(ty, _, body_id), .. })
        | Node::Item(hir::Item { node: hir::ItemKind::Const(ty, body_id), .. })
        | Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Const(ty, body_id), .. })
        | Node::TraitItem(
            hir::TraitItem { node: hir::TraitItemKind::Const(ty, Some(body_id)), .. }
        ) => {
            (*body_id, ty.span)
        }
        Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => {
            (*body, tcx.hir().span(*hir_id))
        }

        _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id),
    };

    tcx.infer_ctxt().enter(|infcx| {
        let cx = Cx::new(&infcx, id);
        let body = if cx.tables().tainted_by_errors {
            build::construct_error(cx, body_id)
        } else if cx.body_owner_kind.is_fn_or_closure() {
            // fetch the fully liberated fn signature (that is, all bound
            // types/lifetimes replaced)
            let fn_sig = cx.tables().liberated_fn_sigs()[id].clone();
            let fn_def_id = tcx.hir().local_def_id(id);

            let ty = tcx.type_of(fn_def_id);
            let mut abi = fn_sig.abi;
            let implicit_argument = match ty.sty {
                ty::Closure(..) => {
                    // HACK(eddyb) Avoid having RustCall on closures,
                    // as it adds unnecessary (and wrong) auto-tupling.
                    abi = Abi::Rust;
                    Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
                }
                ty::Generator(..) => {
                    let gen_ty = tcx.body_tables(body_id).node_type(id);
                    Some(ArgInfo(gen_ty, None, None, None))
                }
                _ => None,
            };

            let safety = match fn_sig.unsafety {
                hir::Unsafety::Normal => Safety::Safe,
                hir::Unsafety::Unsafe => Safety::FnUnsafe,
            };

            let body = tcx.hir().body(body_id);
            let explicit_arguments =
                body.arguments
                    .iter()
                    .enumerate()
                    .map(|(index, arg)| {
                        let owner_id = tcx.hir().body_owner(body_id);
                        let opt_ty_info;
                        let self_arg;
                        if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) {
                            let ty_hir_id = fn_decl.inputs[index].hir_id;
                            let ty_span = tcx.hir().span(ty_hir_id);
                            opt_ty_info = Some(ty_span);
                            self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
                                match fn_decl.implicit_self {
                                    hir::ImplicitSelfKind::Imm => Some(ImplicitSelfKind::Imm),
                                    hir::ImplicitSelfKind::Mut => Some(ImplicitSelfKind::Mut),
                                    hir::ImplicitSelfKind::ImmRef => Some(ImplicitSelfKind::ImmRef),
                                    hir::ImplicitSelfKind::MutRef => Some(ImplicitSelfKind::MutRef),
                                    _ => None,
                                }
                            } else {
                                None
                            };
                        } else {
                            opt_ty_info = None;
                            self_arg = None;
                        }

                        ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&arg), self_arg)
                    });

            let arguments = implicit_argument.into_iter().chain(explicit_arguments);

            let (yield_ty, return_ty) = if body.generator_kind.is_some() {
                let gen_sig = match ty.sty {
                    ty::Generator(gen_def_id, gen_substs, ..) =>
                        gen_substs.sig(gen_def_id, tcx),
                    _ =>
                        span_bug!(tcx.hir().span(id),
                                  "generator w/o generator type: {:?}", ty),
                };
                (Some(gen_sig.yield_ty), gen_sig.return_ty)
            } else {
                (None, fn_sig.output())
            };

            build::construct_fn(cx, id, arguments, safety, abi,
                                return_ty, yield_ty, return_ty_span, body)
        } else {
            // Get the revealed type of this const. This is *not* the adjusted
            // type of its body, which may be a subtype of this type. For
            // example:
            //
            // fn foo(_: &()) {}
            // static X: fn(&'static ()) = foo;
            //
            // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
            // is not the same as the type of X. We need the type of the return
            // place to be the type of the constant because NLL typeck will
            // equate them.

            let return_ty = cx.tables().node_type(id);

            build::construct_const(cx, body_id, return_ty, return_ty_span)
        };

        mir_util::dump_mir(tcx, None, "mir_map", &0,
                           MirSource::item(def_id), &body, |_, _| Ok(()) );

        lints::check(tcx, &body, def_id);

        body
    })
}

///////////////////////////////////////////////////////////////////////////
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from

fn liberated_closure_env_ty(
    tcx: TyCtxt<'_>,
    closure_expr_id: hir::HirId,
    body_id: hir::BodyId,
) -> Ty<'_> {
    let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_id);

    let (closure_def_id, closure_substs) = match closure_ty.sty {
        ty::Closure(closure_def_id, closure_substs) => (closure_def_id, closure_substs),
        _ => bug!("closure expr does not have closure type: {:?}", closure_ty)
    };

    let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs).unwrap();
    tcx.liberate_late_bound_regions(closure_def_id, &closure_env_ty)
}

#[derive(Debug, PartialEq, Eq)]
pub enum BlockFrame {
    /// Evaluation is currently within a statement.
    ///
    /// Examples include:
    /// 1. `EXPR;`
    /// 2. `let _ = EXPR;`
    /// 3. `let x = EXPR;`
    Statement {
        /// If true, then statement discards result from evaluating
        /// the expression (such as examples 1 and 2 above).
        ignores_expr_result: bool
    },

    /// Evaluation is currently within the tail expression of a block.
    ///
    /// Example: `{ STMT_1; STMT_2; EXPR }`
    TailExpr {
        /// If true, then the surrounding context of the block ignores
        /// the result of evaluating the block's tail expression.
        ///
        /// Example: `let _ = { STMT_1; EXPR };`
        tail_result_is_ignored: bool
    },

    /// Generic mark meaning that the block occurred as a subexpression
    /// where the result might be used.
    ///
    /// Examples: `foo(EXPR)`, `match EXPR { ... }`
    SubExpr,
}

impl BlockFrame {
    fn is_tail_expr(&self) -> bool {
        match *self {
            BlockFrame::TailExpr { .. } => true,

            BlockFrame::Statement { .. } |
            BlockFrame::SubExpr => false,
        }
    }
    fn is_statement(&self) -> bool {
        match *self {
            BlockFrame::Statement { .. } => true,

            BlockFrame::TailExpr { .. } |
            BlockFrame::SubExpr => false,
        }
    }
 }

#[derive(Debug)]
struct BlockContext(Vec<BlockFrame>);

struct Builder<'a, 'tcx> {
    hir: Cx<'a, 'tcx>,
    cfg: CFG<'tcx>,

    fn_span: Span,
    arg_count: usize,
    is_generator: bool,

    /// The current set of scopes, updated as we traverse;
    /// see the `scope` module for more details.
    scopes: scope::Scopes<'tcx>,

    /// The block-context: each time we build the code within an hair::Block,
    /// we push a frame here tracking whether we are building a statement or
    /// if we are pushing the tail expression of the block. This is used to
    /// embed information in generated temps about whether they were created
    /// for a block tail expression or not.
    ///
    /// It would be great if we could fold this into `self.scopes`
    /// somehow, but right now I think that is very tightly tied to
    /// the code generation in ways that we cannot (or should not)
    /// start just throwing new entries onto that vector in order to
    /// distinguish the context of EXPR1 from the context of EXPR2 in
    /// `{ STMTS; EXPR1 } + EXPR2`.
    block_context: BlockContext,

    /// The current unsafe block in scope, even if it is hidden by
    /// a `PushUnsafeBlock`.
    unpushed_unsafe: Safety,

    /// The number of `push_unsafe_block` levels in scope.
    push_unsafe_count: usize,

    /// The vector of all scopes that we have created thus far;
    /// we track this for debuginfo later.
    source_scopes: IndexVec<SourceScope, SourceScopeData>,
    source_scope_local_data: IndexVec<SourceScope, SourceScopeLocalData>,
    source_scope: SourceScope,

    /// The guard-context: each time we build the guard expression for
    /// a match arm, we push onto this stack, and then pop when we
    /// finish building it.
    guard_context: Vec<GuardFrame>,

    /// Maps `HirId`s of variable bindings to the `Local`s created for them.
    /// (A match binding can have two locals; the 2nd is for the arm's guard.)
    var_indices: HirIdMap<LocalsForNode>,
    local_decls: IndexVec<Local, LocalDecl<'tcx>>,
    canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
    __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
    upvar_mutbls: Vec<Mutability>,
    unit_temp: Option<Place<'tcx>>,

    /// Cached block with the `RESUME` terminator; this is created
    /// when first set of cleanups are built.
    cached_resume_block: Option<BasicBlock>,
    /// Cached block with the `RETURN` terminator.
    cached_return_block: Option<BasicBlock>,
    /// Cached block with the `UNREACHABLE` terminator.
    cached_unreachable_block: Option<BasicBlock>,
}

impl<'a, 'tcx> Builder<'a, 'tcx> {
    fn is_bound_var_in_guard(&self, id: hir::HirId) -> bool {
        self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id))
    }

    fn var_local_id(&self, id: hir::HirId, for_guard: ForGuard) -> Local {
        self.var_indices[&id].local_id(for_guard)
    }
}

impl BlockContext {
    fn new() -> Self { BlockContext(vec![]) }
    fn push(&mut self, bf: BlockFrame) { self.0.push(bf); }
    fn pop(&mut self) -> Option<BlockFrame> { self.0.pop() }

    /// Traverses the frames on the `BlockContext`, searching for either
    /// the first block-tail expression frame with no intervening
    /// statement frame.
    ///
    /// Notably, this skips over `SubExpr` frames; this method is
    /// meant to be used in the context of understanding the
    /// relationship of a temp (created within some complicated
    /// expression) with its containing expression, and whether the
    /// value of that *containing expression* (not the temp!) is
    /// ignored.
    fn currently_in_block_tail(&self) -> Option<BlockTailInfo> {
        for bf in self.0.iter().rev() {
            match bf {
                BlockFrame::SubExpr => continue,
                BlockFrame::Statement { .. } => break,
                &BlockFrame::TailExpr { tail_result_is_ignored } =>
                    return Some(BlockTailInfo { tail_result_is_ignored })
            }
        }

        return None;
    }

    /// Looks at the topmost frame on the BlockContext and reports
    /// whether its one that would discard a block tail result.
    ///
    /// Unlike `currently_within_ignored_tail_expression`, this does
    /// *not* skip over `SubExpr` frames: here, we want to know
    /// whether the block result itself is discarded.
    fn currently_ignores_tail_results(&self) -> bool {
        match self.0.last() {
            // no context: conservatively assume result is read
            None => false,

            // sub-expression: block result feeds into some computation
            Some(BlockFrame::SubExpr) => false,

            // otherwise: use accumulated is_ignored state.
            Some(BlockFrame::TailExpr { tail_result_is_ignored: ignored }) |
            Some(BlockFrame::Statement { ignores_expr_result: ignored }) => *ignored,
        }
    }
}

#[derive(Debug)]
enum LocalsForNode {
    /// In the usual case, a `HirId` for an identifier maps to at most
    /// one `Local` declaration.
    One(Local),

    /// The exceptional case is identifiers in a match arm's pattern
    /// that are referenced in a guard of that match arm. For these,
    /// we have `2` Locals.
    ///
    /// * `for_arm_body` is the Local used in the arm body (which is
    ///   just like the `One` case above),
    ///
    /// * `ref_for_guard` is the Local used in the arm's guard (which
    ///   is a reference to a temp that is an alias of
    ///   `for_arm_body`).
    ForGuard { ref_for_guard: Local, for_arm_body: Local },
}

#[derive(Debug)]
struct GuardFrameLocal {
    id: hir::HirId,
}

impl GuardFrameLocal {
    fn new(id: hir::HirId, _binding_mode: BindingMode) -> Self {
        GuardFrameLocal {
            id: id,
        }
    }
}

#[derive(Debug)]
struct GuardFrame {
    /// These are the id's of names that are bound by patterns of the
    /// arm of *this* guard.
    ///
    /// (Frames higher up the stack will have the id's bound in arms
    /// further out, such as in a case like:
    ///
    /// match E1 {
    ///      P1(id1) if (... (match E2 { P2(id2) if ... => B2 })) => B1,
    /// }
    ///
    /// here, when building for FIXME.
    locals: Vec<GuardFrameLocal>,
}

/// `ForGuard` indicates whether we are talking about:
///   1. The variable for use outside of guard expressions, or
///   2. The temp that holds reference to (1.), which is actually what the
///      guard expressions see.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum ForGuard {
    RefWithinGuard,
    OutsideGuard,
}

impl LocalsForNode {
    fn local_id(&self, for_guard: ForGuard) -> Local {
        match (self, for_guard) {
            (&LocalsForNode::One(local_id), ForGuard::OutsideGuard) |
            (&LocalsForNode::ForGuard { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
            (&LocalsForNode::ForGuard { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
                local_id,

            (&LocalsForNode::One(_), ForGuard::RefWithinGuard) =>
                bug!("anything with one local should never be within a guard."),
        }
    }
}

struct CFG<'tcx> {
    basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
}

newtype_index! {
    pub struct ScopeId { .. }
}

///////////////////////////////////////////////////////////////////////////
/// The `BlockAnd` "monad" packages up the new basic block along with a
/// produced value (sometimes just unit, of course). The `unpack!`
/// macro (and methods below) makes working with `BlockAnd` much more
/// convenient.

#[must_use = "if you don't use one of these results, you're leaving a dangling edge"]
struct BlockAnd<T>(BasicBlock, T);

trait BlockAndExtension {
    fn and<T>(self, v: T) -> BlockAnd<T>;
    fn unit(self) -> BlockAnd<()>;
}

impl BlockAndExtension for BasicBlock {
    fn and<T>(self, v: T) -> BlockAnd<T> {
        BlockAnd(self, v)
    }

    fn unit(self) -> BlockAnd<()> {
        BlockAnd(self, ())
    }
}

/// Update a block pointer and return the value.
/// Use it like `let x = unpack!(block = self.foo(block, foo))`.
macro_rules! unpack {
    ($x:ident = $c:expr) => {
        {
            let BlockAnd(b, v) = $c;
            $x = b;
            v
        }
    };

    ($c:expr) => {
        {
            let BlockAnd(b, ()) = $c;
            b
        }
    };
}

fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
    // Not callable from C, so we can safely unwind through these
    if abi == Abi::Rust || abi == Abi::RustCall { return false; }

    // Validate `#[unwind]` syntax regardless of platform-specific panic strategy
    let attrs = &tcx.get_attrs(fn_def_id);
    let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs);

    // We never unwind, so it's not relevant to stop an unwind
    if tcx.sess.panic_strategy() != PanicStrategy::Unwind { return false; }

    // We cannot add landing pads, so don't add one
    if tcx.sess.no_landing_pads() { return false; }

    // This is a special case: some functions have a C abi but are meant to
    // unwind anyway. Don't stop them.
    match unwind_attr {
        None => false, // FIXME(#58794)
        Some(UnwindAttr::Allowed) => false,
        Some(UnwindAttr::Aborts) => true,
    }
}

///////////////////////////////////////////////////////////////////////////
/// the main entry point for building MIR for a function

struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Arg>, Option<ImplicitSelfKind>);

fn construct_fn<'a, 'tcx, A>(
    hir: Cx<'a, 'tcx>,
    fn_id: hir::HirId,
    arguments: A,
    safety: Safety,
    abi: Abi,
    return_ty: Ty<'tcx>,
    yield_ty: Option<Ty<'tcx>>,
    return_ty_span: Span,
    body: &'tcx hir::Body,
) -> Body<'tcx>
where
    A: Iterator<Item=ArgInfo<'tcx>>
{
    let arguments: Vec<_> = arguments.collect();

    let tcx = hir.tcx();
    let tcx_hir = tcx.hir();
    let span = tcx_hir.span(fn_id);

    let hir_tables = hir.tables();
    let fn_def_id = tcx_hir.local_def_id(fn_id);

    // Gather the upvars of a closure, if any.
    let mut upvar_mutbls = vec![];
    // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
    // closure and we stored in a map called upvar_list in TypeckTables indexed
    // with the closure's DefId. Here, we run through that vec of UpvarIds for
    // the given closure and use the necessary information to create UpvarDecl.
    let upvar_debuginfo: Vec<_> = hir_tables
        .upvar_list
        .get(&fn_def_id)
        .into_iter()
        .flatten()
        .map(|(&var_hir_id, &upvar_id)| {
            let capture = hir_tables.upvar_capture(upvar_id);
            let by_ref = match capture {
                ty::UpvarCapture::ByValue => false,
                ty::UpvarCapture::ByRef(..) => true,
            };
            let mut debuginfo = UpvarDebuginfo {
                debug_name: kw::Invalid,
                by_ref,
            };
            let mut mutability = Mutability::Not;
            if let Some(Node::Binding(pat)) = tcx_hir.find(var_hir_id) {
                if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                    debuginfo.debug_name = ident.name;
                    if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
                        if bm == ty::BindByValue(hir::MutMutable) {
                            mutability = Mutability::Mut;
                        } else {
                            mutability = Mutability::Not;
                        }
                    } else {
                        tcx.sess.delay_span_bug(pat.span, "missing binding mode");
                    }
                }
            }
            upvar_mutbls.push(mutability);
            debuginfo
        })
        .collect();

    let mut builder = Builder::new(hir,
        span,
        arguments.len(),
        safety,
        return_ty,
        return_ty_span,
        upvar_debuginfo,
        upvar_mutbls,
        body.generator_kind.is_some());

    let call_site_scope = region::Scope {
        id: body.value.hir_id.local_id,
        data: region::ScopeData::CallSite
    };
    let arg_scope = region::Scope {
        id: body.value.hir_id.local_id,
        data: region::ScopeData::Arguments
    };
    let mut block = START_BLOCK;
    let source_info = builder.source_info(span);
    let call_site_s = (call_site_scope, source_info);
    unpack!(block = builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
        if should_abort_on_panic(tcx, fn_def_id, abi) {
            builder.schedule_abort();
        }

        let arg_scope_s = (arg_scope, source_info);
        // `return_block` is called when we evaluate a `return` expression, so
        // we just use `START_BLOCK` here.
        unpack!(block = builder.in_breakable_scope(
            None,
            START_BLOCK,
            Place::RETURN_PLACE,
            |builder| {
                builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
                    builder.args_and_body(block, &arguments, arg_scope, &body.value)
                })
            },
        ));
        // Attribute epilogue to function's closing brace
        let fn_end = span.shrink_to_hi();
        let source_info = builder.source_info(fn_end);
        let return_block = builder.return_block();
        builder.cfg.terminate(block, source_info,
                              TerminatorKind::Goto { target: return_block });
        builder.cfg.terminate(return_block, source_info,
                              TerminatorKind::Return);
        // Attribute any unreachable codepaths to the function's closing brace
        if let Some(unreachable_block) = builder.cached_unreachable_block {
            builder.cfg.terminate(unreachable_block, source_info,
                                  TerminatorKind::Unreachable);
        }
        return_block.unit()
    }));
    assert_eq!(block, builder.return_block());

    let mut spread_arg = None;
    if abi == Abi::RustCall {
        // RustCall pseudo-ABI untuples the last argument.
        spread_arg = Some(Local::new(arguments.len()));
    }
    info!("fn_id {:?} has attrs {:?}", fn_def_id,
          tcx.get_attrs(fn_def_id));

    let mut body = builder.finish(yield_ty);
    body.spread_arg = spread_arg;
    body
}

fn construct_const<'a, 'tcx>(
    hir: Cx<'a, 'tcx>,
    body_id: hir::BodyId,
    const_ty: Ty<'tcx>,
    const_ty_span: Span,
) -> Body<'tcx> {
    let tcx = hir.tcx();
    let owner_id = tcx.hir().body_owner(body_id);
    let span = tcx.hir().span(owner_id);
    let mut builder = Builder::new(
        hir,
        span,
        0,
        Safety::Safe,
        const_ty,
        const_ty_span,
        vec![],
        vec![],
        false,
    );

    let mut block = START_BLOCK;
    let ast_expr = &tcx.hir().body(body_id).value;
    let expr = builder.hir.mirror(ast_expr);
    unpack!(block = builder.into_expr(&Place::RETURN_PLACE, block, expr));

    let source_info = builder.source_info(span);
    builder.cfg.terminate(block, source_info, TerminatorKind::Return);

    // Constants can't `return` so a return block should not be created.
    assert_eq!(builder.cached_return_block, None);

    // Constants may be match expressions in which case an unreachable block may
    // be created, so terminate it properly.
    if let Some(unreachable_block) = builder.cached_unreachable_block {
        builder.cfg.terminate(unreachable_block, source_info,
                              TerminatorKind::Unreachable);
    }

    builder.finish(None)
}

fn construct_error<'a, 'tcx>(
    hir: Cx<'a, 'tcx>,
    body_id: hir::BodyId
) -> Body<'tcx> {
    let owner_id = hir.tcx().hir().body_owner(body_id);
    let span = hir.tcx().hir().span(owner_id);
    let ty = hir.tcx().types.err;
    let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, vec![], vec![], false);
    let source_info = builder.source_info(span);
    builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
    builder.finish(None)
}

impl<'a, 'tcx> Builder<'a, 'tcx> {
    fn new(hir: Cx<'a, 'tcx>,
           span: Span,
           arg_count: usize,
           safety: Safety,
           return_ty: Ty<'tcx>,
           return_span: Span,
           __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
           upvar_mutbls: Vec<Mutability>,
           is_generator: bool)
           -> Builder<'a, 'tcx> {
        let lint_level = LintLevel::Explicit(hir.root_lint_level);
        let mut builder = Builder {
            hir,
            cfg: CFG { basic_blocks: IndexVec::new() },
            fn_span: span,
            arg_count,
            is_generator,
            scopes: Default::default(),
            block_context: BlockContext::new(),
            source_scopes: IndexVec::new(),
            source_scope: OUTERMOST_SOURCE_SCOPE,
            source_scope_local_data: IndexVec::new(),
            guard_context: vec![],
            push_unsafe_count: 0,
            unpushed_unsafe: safety,
            local_decls: IndexVec::from_elem_n(
                LocalDecl::new_return_place(return_ty, return_span),
                1,
            ),
            canonical_user_type_annotations: IndexVec::new(),
            __upvar_debuginfo_codegen_only_do_not_use,
            upvar_mutbls,
            var_indices: Default::default(),
            unit_temp: None,
            cached_resume_block: None,
            cached_return_block: None,
            cached_unreachable_block: None,
        };

        assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
        assert_eq!(
            builder.new_source_scope(span, lint_level, Some(safety)),
            OUTERMOST_SOURCE_SCOPE);
        builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None;

        builder
    }

    fn finish(self,
              yield_ty: Option<Ty<'tcx>>)
              -> Body<'tcx> {
        for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
            if block.terminator.is_none() {
                span_bug!(self.fn_span, "no terminator on block {:?}", index);
            }
        }

        Body::new(
            self.cfg.basic_blocks,
            self.source_scopes,
            ClearCrossCrate::Set(self.source_scope_local_data),
            IndexVec::new(),
            yield_ty,
            self.local_decls,
            self.canonical_user_type_annotations,
            self.arg_count,
            self.__upvar_debuginfo_codegen_only_do_not_use,
            self.fn_span,
            self.hir.control_flow_destroyed(),
        )
    }

    fn args_and_body(&mut self,
                     mut block: BasicBlock,
                     arguments: &[ArgInfo<'tcx>],
                     argument_scope: region::Scope,
                     ast_body: &'tcx hir::Expr)
                     -> BlockAnd<()>
    {
        // Allocate locals for the function arguments
        for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
            // If this is a simple binding pattern, give the local a name for
            // debuginfo and so that error reporting knows that this is a user
            // variable. For any other pattern the pattern introduces new
            // variables which will be named instead.
            let (name, span) = if let Some(arg) = arg_opt {
                (arg.pat.simple_ident().map(|ident| ident.name), arg.pat.span)
            } else {
                (None, self.fn_span)
            };

            let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span, };
            self.local_decls.push(LocalDecl {
                mutability: Mutability::Mut,
                ty,
                user_ty: UserTypeProjections::none(),
                source_info,
                visibility_scope: source_info.scope,
                name,
                internal: false,
                is_user_variable: None,
                is_block_tail: None,
            });
        }

        let mut scope = None;
        // Bind the argument patterns
        for (index, arg_info) in arguments.iter().enumerate() {
            // Function arguments always get the first Local indices after the return place
            let local = Local::new(index + 1);
            let place = Place::from(local);
            let &ArgInfo(ty, opt_ty_info, arg_opt, ref self_binding) = arg_info;

            // Make sure we drop (parts of) the argument even when not matched on.
            self.schedule_drop(
                arg_opt.as_ref().map_or(ast_body.span, |arg| arg.pat.span),
                argument_scope, local, ty, DropKind::Value,
            );

            if let Some(arg) = arg_opt {
                let pattern = self.hir.pattern_from_hir(&arg.pat);
                let original_source_scope = self.source_scope;
                let span = pattern.span;
                self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
                match *pattern.kind {
                    // Don't introduce extra copies for simple bindings
                    PatternKind::Binding {
                        mutability,
                        var,
                        mode: BindingMode::ByValue,
                        subpattern: None,
                        ..
                    } => {
                        self.local_decls[local].mutability = mutability;
                        self.local_decls[local].source_info.scope = self.source_scope;
                        self.local_decls[local].is_user_variable =
                            if let Some(kind) = self_binding {
                                Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind)))
                            } else {
                                let binding_mode = ty::BindingMode::BindByValue(mutability.into());
                                Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                                    binding_mode,
                                    opt_ty_info,
                                    opt_match_place: Some((Some(place.clone()), span)),
                                    pat_span: span,
                                })))
                            };
                        self.var_indices.insert(var, LocalsForNode::One(local));
                    }
                    _ => {
                        scope = self.declare_bindings(
                            scope,
                            ast_body.span,
                            &pattern,
                            matches::ArmHasGuard(false),
                            Some((Some(&place), span)),
                        );
                        unpack!(block = self.place_into_pattern(block, pattern, &place, false));
                    }
                }
                self.source_scope = original_source_scope;
            }
        }

        // Enter the argument pattern bindings source scope, if it exists.
        if let Some(source_scope) = scope {
            self.source_scope = source_scope;
        }

        let body = self.hir.mirror(ast_body);
        self.into(&Place::RETURN_PLACE, block, body)
    }

    fn set_correct_source_scope_for_arg(
        &mut self,
        arg_hir_id: hir::HirId,
        original_source_scope: SourceScope,
        pattern_span: Span
    ) {
        let tcx = self.hir.tcx();
        let current_root = tcx.maybe_lint_level_root_bounded(
            arg_hir_id,
            self.hir.root_lint_level
        );
        let parent_root = tcx.maybe_lint_level_root_bounded(
            self.source_scope_local_data[original_source_scope].lint_root,
            self.hir.root_lint_level,
        );
        if current_root != parent_root {
            self.source_scope = self.new_source_scope(
                pattern_span,
                LintLevel::Explicit(current_root),
                None
            );
        }
    }

    fn get_unit_temp(&mut self) -> Place<'tcx> {
        match self.unit_temp {
            Some(ref tmp) => tmp.clone(),
            None => {
                let ty = self.hir.unit_ty();
                let fn_span = self.fn_span;
                let tmp = self.temp(ty, fn_span);
                self.unit_temp = Some(tmp.clone());
                tmp
            }
        }
    }

    fn return_block(&mut self) -> BasicBlock {
        match self.cached_return_block {
            Some(rb) => rb,
            None => {
                let rb = self.cfg.start_new_block();
                self.cached_return_block = Some(rb);
                rb
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////
// Builder methods are broken up into modules, depending on what kind
// of thing is being lowered. Note that they use the `unpack` macro
// above extensively.

mod block;
mod cfg;
mod expr;
mod into;
mod matches;
mod misc;
mod scope;
