// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Standalone Tests for the Inference Module

use std::path::PathBuf;
use std::sync::mpsc;

use driver;
use rustc_lint;
use rustc_resolve::MakeGlobMap;
use rustc::middle::region;
use rustc::ty::subst::Subst;
use rustc::traits::ObligationCause;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::query::OnDiskCache;
use rustc::infer::{self, InferOk, InferResult};
use rustc::infer::outlives::env::OutlivesEnvironment;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc_metadata::cstore::CStore;
use rustc::hir::map as hir_map;
use rustc::session::{self, config};
use rustc::session::config::{OutputFilenames, OutputTypes};
use rustc_data_structures::sync::{self, Lrc};
use syntax;
use syntax::ast;
use rustc_target::spec::abi::Abi;
use syntax::codemap::{CodeMap, FilePathMapping, FileName};
use errors;
use errors::emitter::Emitter;
use errors::{Level, DiagnosticBuilder};
use syntax::feature_gate::UnstableFeatures;
use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;

use rustc::hir;

struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>,
    region_scope_tree: &'a mut region::ScopeTree,
    param_env: ty::ParamEnv<'tcx>,
}

struct RH<'a> {
    id: hir::ItemLocalId,
    sub: &'a [RH<'a>],
}

const EMPTY_SOURCE_STR: &'static str = "#![feature(no_core)] #![no_core]";

struct ExpectErrorEmitter {
    messages: Vec<String>,
}

fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
    match lvl {
        Level::Bug | Level::Fatal | Level::Error => {}
        _ => {
            return;
        }
    }

    debug!("Error: {}", msg);
    match e.messages.iter().position(|m| msg.contains(m)) {
        Some(i) => {
            e.messages.remove(i);
        }
        None => {
            debug!("Unexpected error: {} Expected: {:?}", msg, e.messages);
            panic!("Unexpected error: {} Expected: {:?}", msg, e.messages);
        }
    }
}

impl Emitter for ExpectErrorEmitter {
    fn emit(&mut self, db: &DiagnosticBuilder) {
        remove_message(self, &db.message(), db.level);
        for child in &db.children {
            remove_message(self, &child.message(), child.level);
        }
    }
}

fn errors(msgs: &[&str]) -> (Box<dyn Emitter + sync::Send>, usize) {
    let v = msgs.iter().map(|m| m.to_string()).collect();
    (box ExpectErrorEmitter { messages: v } as Box<dyn Emitter + sync::Send>, msgs.len())
}

fn test_env<F>(source_string: &str,
               args: (Box<dyn Emitter + sync::Send>, usize),
               body: F)
    where F: FnOnce(Env)
{
    syntax::with_globals(|| {
        let mut options = config::Options::default();
        options.debugging_opts.verbose = true;
        options.unstable_features = UnstableFeatures::Allow;

        driver::spawn_thread_pool(options, |options| {
            test_env_with_pool(options, source_string, args, body)
        })
    });
}

fn test_env_with_pool<F>(
    options: config::Options,
    source_string: &str,
    (emitter, expected_err_count): (Box<dyn Emitter + sync::Send>, usize),
    body: F
)
    where F: FnOnce(Env)
{
    let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter);
    let sess = session::build_session_(options,
                                       None,
                                       diagnostic_handler,
                                       Lrc::new(CodeMap::new(FilePathMapping::empty())));
    let cstore = CStore::new(::get_codegen_backend(&sess).metadata_loader());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
    let input = config::Input::Str {
        name: FileName::Anon,
        input: source_string.to_string(),
    };
    let krate = driver::phase_1_parse_input(&driver::CompileController::basic(),
                                            &sess,
                                            &input).unwrap();
    let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = {
        driver::phase_2_configure_and_expand(&sess,
                                             &cstore,
                                             krate,
                                             None,
                                             "test",
                                             None,
                                             MakeGlobMap::No,
                                             |_| Ok(()))
            .expect("phase 2 aborted")
    };

    let arenas = ty::AllArenas::new();
    let hir_map = hir_map::map_crate(&sess, &cstore, &mut hir_forest, &defs);

    // run just enough stuff to build a tcx:
    let (tx, _rx) = mpsc::channel();
    let outputs = OutputFilenames {
        out_directory: PathBuf::new(),
        out_filestem: String::new(),
        single_output_file: None,
        extra: String::new(),
        outputs: OutputTypes::new(&[]),
    };
    TyCtxt::create_and_enter(&sess,
                             &cstore,
                             ty::query::Providers::default(),
                             ty::query::Providers::default(),
                             &arenas,
                             resolutions,
                             hir_map,
                             OnDiskCache::new_empty(sess.codemap()),
                             "test_crate",
                             tx,
                             &outputs,
                             |tcx| {
        tcx.infer_ctxt().enter(|infcx| {
            let mut region_scope_tree = region::ScopeTree::default();
            let param_env = ty::ParamEnv::empty();
            body(Env {
                infcx: &infcx,
                region_scope_tree: &mut region_scope_tree,
                param_env: param_env,
            });
            let outlives_env = OutlivesEnvironment::new(param_env);
            let def_id = tcx.hir.local_def_id(ast::CRATE_NODE_ID);
            infcx.resolve_regions_and_report_errors(def_id, &region_scope_tree, &outlives_env);
            assert_eq!(tcx.sess.err_count(), expected_err_count);
        });
    });
}

const D1: ty::DebruijnIndex = ty::INNERMOST;
const D2: ty::DebruijnIndex = D1.shifted_in(1);

impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
    pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
        self.infcx.tcx
    }

    pub fn create_region_hierarchy(&mut self, rh: &RH,
                                   parent: (region::Scope, region::ScopeDepth)) {
        let me = region::Scope::Node(rh.id);
        self.region_scope_tree.record_scope_parent(me, Some(parent));
        for child_rh in rh.sub {
            self.create_region_hierarchy(child_rh, (me, parent.1 + 1));
        }
    }

    pub fn create_simple_region_hierarchy(&mut self) {
        // creates a region hierarchy where 1 is root, 10 and 11 are
        // children of 1, etc

        let dscope = region::Scope::Destruction(hir::ItemLocalId(1));
        self.region_scope_tree.record_scope_parent(dscope, None);
        self.create_region_hierarchy(&RH {
            id: hir::ItemLocalId(1),
            sub: &[RH {
                id: hir::ItemLocalId(10),
                sub: &[],
            },
            RH {
                id: hir::ItemLocalId(11),
                sub: &[],
            }],
        }, (dscope, 1));
    }

    #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
    pub fn lookup_item(&self, names: &[String]) -> ast::NodeId {
        return match search_mod(self, &self.infcx.tcx.hir.krate().module, 0, names) {
            Some(id) => id,
            None => {
                panic!("no item found: `{}`", names.join("::"));
            }
        };

        fn search_mod(this: &Env,
                      m: &hir::Mod,
                      idx: usize,
                      names: &[String])
                      -> Option<ast::NodeId> {
            assert!(idx < names.len());
            for item in &m.item_ids {
                let item = this.infcx.tcx.hir.expect_item(item.id);
                if item.name.to_string() == names[idx] {
                    return search(this, item, idx + 1, names);
                }
            }
            return None;
        }

        fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<ast::NodeId> {
            if idx == names.len() {
                return Some(it.id);
            }

            return match it.node {
                hir::ItemKind::Use(..) |
                hir::ItemKind::ExternCrate(..) |
                hir::ItemKind::Const(..) |
                hir::ItemKind::Static(..) |
                hir::ItemKind::Fn(..) |
                hir::ItemKind::ForeignMod(..) |
                hir::ItemKind::GlobalAsm(..) |
                hir::ItemKind::Existential(..) |
                hir::ItemKind::Ty(..) => None,

                hir::ItemKind::Enum(..) |
                hir::ItemKind::Struct(..) |
                hir::ItemKind::Union(..) |
                hir::ItemKind::Trait(..) |
                hir::ItemKind::TraitAlias(..) |
                hir::ItemKind::Impl(..) => None,

                hir::ItemKind::Mod(ref m) => search_mod(this, m, idx, names),
            };
        }
    }

    pub fn make_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
        match self.infcx.at(&ObligationCause::dummy(), self.param_env).sub(a, b) {
            Ok(_) => true,
            Err(ref e) => panic!("Encountered error: {}", e),
        }
    }

    pub fn is_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
        self.infcx.can_sub(self.param_env, a, b).is_ok()
    }

    pub fn assert_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) {
        if !self.is_subtype(a, b) {
            panic!("{} is not a subtype of {}, but it should be", a, b);
        }
    }

    pub fn assert_eq(&self, a: Ty<'tcx>, b: Ty<'tcx>) {
        self.assert_subtype(a, b);
        self.assert_subtype(b, a);
    }

    pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> {
        self.infcx.tcx.mk_fn_ptr(ty::Binder::bind(self.infcx.tcx.mk_fn_sig(
            input_tys.iter().cloned(),
            output_ty,
            false,
            hir::Unsafety::Normal,
            Abi::Rust
        )))
    }

    pub fn t_nil(&self) -> Ty<'tcx> {
        self.infcx.tcx.mk_nil()
    }

    pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
        self.infcx.tcx.intern_tup(&[ty1, ty2])
    }

    pub fn t_param(&self, index: u32) -> Ty<'tcx> {
        let name = format!("T{}", index);
        self.infcx.tcx.mk_ty_param(index, Symbol::intern(&name).as_interned_str())
    }

    pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> {
        let name = Symbol::intern(name).as_interned_str();
        self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
            def_id: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
            index,
            name,
        }))
    }

    pub fn re_late_bound_with_debruijn(&self,
                                       id: u32,
                                       debruijn: ty::DebruijnIndex)
                                       -> ty::Region<'tcx> {
        self.infcx.tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
    }

    pub fn t_rptr(&self, r: ty::Region<'tcx>) -> Ty<'tcx> {
        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
    }

    pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> {
        let r = self.re_late_bound_with_debruijn(id, D1);
        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
    }

    pub fn t_rptr_late_bound_with_debruijn(&self,
                                           id: u32,
                                           debruijn: ty::DebruijnIndex)
                                           -> Ty<'tcx> {
        let r = self.re_late_bound_with_debruijn(id, debruijn);
        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
    }

    pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> {
        let r = ty::ReScope(region::Scope::Node(hir::ItemLocalId(id)));
        self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
    }

    pub fn re_free(&self, id: u32) -> ty::Region<'tcx> {
        self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
            scope: self.infcx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
            bound_region: ty::BrAnon(id),
        }))
    }

    pub fn t_rptr_free(&self, id: u32) -> Ty<'tcx> {
        let r = self.re_free(id);
        self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
    }

    pub fn sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> InferResult<'tcx, ()> {
        self.infcx.at(&ObligationCause::dummy(), self.param_env).sub(t1, t2)
    }

    /// Checks that `t1 <: t2` is true (this may register additional
    /// region checks).
    pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
        match self.sub(t1, t2) {
            Ok(InferOk { obligations, value: () }) => {
                // None of these tests should require nested obligations:
                assert!(obligations.is_empty());
            }
            Err(ref e) => {
                panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, e);
            }
        }
    }

    /// Checks that `t1 <: t2` is false (this may register additional
    /// region checks).
    pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
        match self.sub(t1, t2) {
            Err(_) => {}
            Ok(_) => {
                panic!("unexpected success computing sub({:?},{:?})", t1, t2);
            }
        }
    }
}

#[test]
fn contravariant_region_ptr_ok() {
    test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
        env.create_simple_region_hierarchy();
        let t_rptr1 = env.t_rptr_scope(1);
        let t_rptr10 = env.t_rptr_scope(10);
        env.assert_eq(t_rptr1, t_rptr1);
        env.assert_eq(t_rptr10, t_rptr10);
        env.make_subtype(t_rptr1, t_rptr10);
    })
}

#[test]
fn contravariant_region_ptr_err() {
    test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |mut env| {
        env.create_simple_region_hierarchy();
        let t_rptr1 = env.t_rptr_scope(1);
        let t_rptr10 = env.t_rptr_scope(10);
        env.assert_eq(t_rptr1, t_rptr1);
        env.assert_eq(t_rptr10, t_rptr10);

        // will cause an error when regions are resolved
        env.make_subtype(t_rptr10, t_rptr1);
    })
}

#[test]
fn sub_free_bound_false() {
    //! Test that:
    //!
    //!     fn(&'a isize) <: for<'b> fn(&'b isize)
    //!
    //! does NOT hold.

    test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
        env.create_simple_region_hierarchy();
        let t_rptr_free1 = env.t_rptr_free(1);
        let t_rptr_bound1 = env.t_rptr_late_bound(1);
        env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
                          env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
    })
}

#[test]
fn sub_bound_free_true() {
    //! Test that:
    //!
    //!     for<'a> fn(&'a isize) <: fn(&'b isize)
    //!
    //! DOES hold.

    test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
        env.create_simple_region_hierarchy();
        let t_rptr_bound1 = env.t_rptr_late_bound(1);
        let t_rptr_free1 = env.t_rptr_free(1);
        env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
    })
}

#[test]
fn sub_free_bound_false_infer() {
    //! Test that:
    //!
    //!     fn(_#1) <: for<'b> fn(&'b isize)
    //!
    //! does NOT hold for any instantiation of `_#1`.

    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        let t_infer1 = env.infcx.next_ty_var(TypeVariableOrigin::MiscVariable(DUMMY_SP));
        let t_rptr_bound1 = env.t_rptr_late_bound(1);
        env.check_not_sub(env.t_fn(&[t_infer1], env.tcx().types.isize),
                          env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
    })
}

/// Test substituting a bound region into a function, which introduces another level of binding.
/// This requires adjusting the Debruijn index.
#[test]
fn subst_ty_renumber_bound() {

    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        // Situation:
        // Theta = [A -> &'a foo]

        let t_rptr_bound1 = env.t_rptr_late_bound(1);

        // t_source = fn(A)
        let t_source = {
            let t_param = env.t_param(0);
            env.t_fn(&[t_param], env.t_nil())
        };

        let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]);
        let t_substituted = t_source.subst(env.infcx.tcx, substs);

        // t_expected = fn(&'a isize)
        let t_expected = {
            let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
            env.t_fn(&[t_ptr_bound2], env.t_nil())
        };

        debug!("subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
               t_source,
               substs,
               t_substituted,
               t_expected);

        assert_eq!(t_substituted, t_expected);
    })
}

/// Test substituting a bound region into a function, which introduces another level of binding.
/// This requires adjusting the Debruijn index.
#[test]
fn subst_ty_renumber_some_bounds() {
    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        // Situation:
        // Theta = [A -> &'a foo]

        let t_rptr_bound1 = env.t_rptr_late_bound(1);

        // t_source = (A, fn(A))
        let t_source = {
            let t_param = env.t_param(0);
            env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
        };

        let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]);
        let t_substituted = t_source.subst(env.infcx.tcx, substs);

        // t_expected = (&'a isize, fn(&'a isize))
        //
        // but not that the Debruijn index is different in the different cases.
        let t_expected = {
            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
            env.t_pair(t_rptr_bound1, env.t_fn(&[t_rptr_bound2], env.t_nil()))
        };

        debug!("subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
               t_source,
               substs,
               t_substituted,
               t_expected);

        assert_eq!(t_substituted, t_expected);
    })
}

/// Test that we correctly compute whether a type has escaping regions or not.
#[test]
fn escaping() {

    test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
        // Situation:
        // Theta = [A -> &'a foo]
        env.create_simple_region_hierarchy();

        assert!(!env.t_nil().has_escaping_regions());

        let t_rptr_free1 = env.t_rptr_free(1);
        assert!(!t_rptr_free1.has_escaping_regions());

        let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, D1);
        assert!(t_rptr_bound1.has_escaping_regions());

        let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
        assert!(t_rptr_bound2.has_escaping_regions());

        // t_fn = fn(A)
        let t_param = env.t_param(0);
        assert!(!t_param.has_escaping_regions());
        let t_fn = env.t_fn(&[t_param], env.t_nil());
        assert!(!t_fn.has_escaping_regions());
    })
}

/// Test applying a substitution where the value being substituted for an early-bound region is a
/// late-bound region.
#[test]
fn subst_region_renumber_region() {
    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        let re_bound1 = env.re_late_bound_with_debruijn(1, D1);

        // type t_source<'a> = fn(&'a isize)
        let t_source = {
            let re_early = env.re_early_bound(0, "'a");
            env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
        };

        let substs = env.infcx.tcx.intern_substs(&[re_bound1.into()]);
        let t_substituted = t_source.subst(env.infcx.tcx, substs);

        // t_expected = fn(&'a isize)
        //
        // but not that the Debruijn index is different in the different cases.
        let t_expected = {
            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
            env.t_fn(&[t_rptr_bound2], env.t_nil())
        };

        debug!("subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
               t_source,
               substs,
               t_substituted,
               t_expected);

        assert_eq!(t_substituted, t_expected);
    })
}

#[test]
fn walk_ty() {
    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        let tcx = env.infcx.tcx;
        let int_ty = tcx.types.isize;
        let usize_ty = tcx.types.usize;
        let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
        let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);
        let walked: Vec<_> = tup2_ty.walk().collect();
        assert_eq!(walked,
                   [tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty,
                    usize_ty, int_ty, usize_ty, usize_ty]);
    })
}

#[test]
fn walk_ty_skip_subtree() {
    test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
        let tcx = env.infcx.tcx;
        let int_ty = tcx.types.isize;
        let usize_ty = tcx.types.usize;
        let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
        let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);

        // types we expect to see (in order), plus a boolean saying
        // whether to skip the subtree.
        let mut expected = vec![(tup2_ty, false),
                                (tup1_ty, false),
                                (int_ty, false),
                                (usize_ty, false),
                                (int_ty, false),
                                (usize_ty, false),
                                (tup1_ty, true), // skip the isize/usize/isize/usize
                                (usize_ty, false)];
        expected.reverse();

        let mut walker = tup2_ty.walk();
        while let Some(t) = walker.next() {
            debug!("walked to {:?}", t);
            let (expected_ty, skip) = expected.pop().unwrap();
            assert_eq!(t, expected_ty);
            if skip {
                walker.skip_current_subtree();
            }
        }

        assert!(expected.is_empty());
    })
}
