use rustc::hir::map::blocks::FnLikeNode;
use rustc::lint::builtin::UNCONDITIONAL_RECURSION;
use rustc::mir::{self, Body, TerminatorKind};
use rustc::ty::subst::InternalSubsts;
use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::FnKind;
use rustc_index::bit_set::BitSet;

crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) {
    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();

    if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
        check_fn_for_unconditional_recursion(tcx, fn_like_node.kind(), body, def_id);
    }
}

fn check_fn_for_unconditional_recursion<'tcx>(
    tcx: TyCtxt<'tcx>,
    fn_kind: FnKind<'_>,
    body: &Body<'tcx>,
    def_id: DefId,
) {
    if let FnKind::Closure(_) = fn_kind {
        // closures can't recur, so they don't matter.
        return;
    }

    //FIXME(#54444) rewrite this lint to use the dataflow framework

    // Walk through this function (say `f`) looking to see if
    // every possible path references itself, i.e., the function is
    // called recursively unconditionally. This is done by trying
    // to find a path from the entry node to the exit node that
    // *doesn't* call `f` by traversing from the entry while
    // pretending that calls of `f` are sinks (i.e., ignoring any
    // exit edges from them).
    //
    // NB. this has an edge case with non-returning statements,
    // like `loop {}` or `panic!()`: control flow never reaches
    // the exit node through these, so one can have a function
    // that never actually calls itself but is still picked up by
    // this lint:
    //
    //     fn f(cond: bool) {
    //         if !cond { panic!() } // could come from `assert!(cond)`
    //         f(false)
    //     }
    //
    // In general, functions of that form may be able to call
    // itself a finite number of times and then diverge. The lint
    // considers this to be an error for two reasons, (a) it is
    // easier to implement, and (b) it seems rare to actually want
    // to have behaviour like the above, rather than
    // e.g., accidentally recursing after an assert.

    let basic_blocks = body.basic_blocks();
    let mut reachable_without_self_call_queue = vec![mir::START_BLOCK];
    let mut reached_exit_without_self_call = false;
    let mut self_call_locations = vec![];
    let mut visited = BitSet::new_empty(basic_blocks.len());

    let param_env = tcx.param_env(def_id);
    let trait_substs_count = match tcx.opt_associated_item(def_id) {
        Some(AssocItem { container: AssocItemContainer::TraitContainer(trait_def_id), .. }) => {
            tcx.generics_of(trait_def_id).count()
        }
        _ => 0,
    };
    let caller_substs = &InternalSubsts::identity_for_item(tcx, def_id)[..trait_substs_count];

    while let Some(bb) = reachable_without_self_call_queue.pop() {
        if !visited.insert(bb) {
            //already done
            continue;
        }

        let block = &basic_blocks[bb];

        if let Some(ref terminator) = block.terminator {
            match terminator.kind {
                TerminatorKind::Call { ref func, .. } => {
                    let func_ty = func.ty(body, tcx);

                    if let ty::FnDef(fn_def_id, substs) = func_ty.kind {
                        let (call_fn_id, call_substs) = if let Some(instance) =
                            Instance::resolve(tcx, param_env, fn_def_id, substs)
                        {
                            (instance.def_id(), instance.substs)
                        } else {
                            (fn_def_id, substs)
                        };

                        let is_self_call = call_fn_id == def_id
                            && &call_substs[..caller_substs.len()] == caller_substs;

                        if is_self_call {
                            self_call_locations.push(terminator.source_info);

                            //this is a self call so we shouldn't explore
                            //further down this path
                            continue;
                        }
                    }
                }
                TerminatorKind::Abort | TerminatorKind::Return => {
                    //found a path!
                    reached_exit_without_self_call = true;
                    break;
                }
                _ => {}
            }

            for successor in terminator.successors() {
                reachable_without_self_call_queue.push(*successor);
            }
        }
    }

    // Check the number of self calls because a function that
    // doesn't return (e.g., calls a `-> !` function or `loop { /*
    // no break */ }`) shouldn't be linted unless it actually
    // recurs.
    if !reached_exit_without_self_call && !self_call_locations.is_empty() {
        let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
        let sp = tcx.sess.source_map().def_span(tcx.hir().span(hir_id));
        let mut db = tcx.struct_span_lint_hir(
            UNCONDITIONAL_RECURSION,
            hir_id,
            sp,
            "function cannot return without recursing",
        );
        db.span_label(sp, "cannot return without recursing");
        // offer some help to the programmer.
        for location in &self_call_locations {
            db.span_label(location.span, "recursive call site");
        }
        db.help("a `loop` may express intention better if this is on purpose");
        db.emit();
    }
}
