diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs deleted file mode 100644 index 0a447a5f8e6fd..0000000000000 --- a/src/librustc/middle/typeck/infer/test.rs +++ /dev/null @@ -1,410 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/** - -# Standalone Tests for the Inference Module - -Note: This module is only compiled when doing unit testing. - -*/ - -use driver::diagnostic; -use driver::driver::{optgroups, build_session_options, build_session}; -use driver::driver::{str_input, build_configuration}; -use middle::lang_items::{LanguageItems, language_items}; -use middle::ty::{FnTyBase, FnMeta, FnSig}; -use util::ppaux::ty_to_str; - -use extra::oldmap::HashMap; -use getopts::{optopt, optmulti, optflag, optflagopt, getopts}; -use getopts::opt_present; -use syntax::codemap::DUMMY_SP; -use syntax::parse::parse_crate_from_source_str; -use syntax::{ast, attr, parse}; - -struct Env { - krate: @ast::Crate, - tcx: ty::ctxt, - infcx: infer::infer_ctxt, - err_messages: @DVec<~str> -} - -struct RH { - id: ast::node_id, - sub: &[RH] -} - -static EMPTY_SOURCE_STR: &str = "/* Hello, world! */"; - -fn setup_env(test_name: &str, source_string: &str) -> Env { - let messages = @DVec(); - let matches = getopts(~[~"-Z", ~"verbose"], optgroups()).get(); - let diag = diagnostic::collect(messages); - let sessopts = build_session_options(~"rustc", &matches, diag); - let sess = build_session(sessopts, None, diag); - let cfg = build_configuration(sess, ~"whatever", str_input(~"")); - let dm = HashMap(); - let amap = HashMap(); - let freevars = HashMap(); - let region_paramd_items = HashMap(); - let region_map = HashMap(); - let lang_items = LanguageItems::new(); - - let parse_sess = parse::new_parse_sess(None); - let krate = parse_crate_from_source_str( - test_name.to_str(), @source_string.to_str(), - cfg, parse_sess); - - let tcx = ty::mk_ctxt(sess, dm, amap, freevars, region_map, - region_paramd_items, lang_items); - - let infcx = infer::new_infer_ctxt(tcx); - - return Env {krate: krate, - tcx: tcx, - infcx: infcx, - err_messages: messages}; -} - -impl Env { - pub fn create_region_hierarchy(&self, rh: &RH) { - for child_rh in rh.sub.iter() { - self.create_region_hierarchy(child_rh); - self.tcx.region_map.insert(child_rh.id, rh.id); - } - } - - pub fn create_simple_region_hierarchy(&self) { - // creates a region hierarchy where 1 is root, 10 and 11 are - // children of 1, etc - self.create_region_hierarchy( - &RH {id: 1, - sub: &[RH {id: 10, - sub: &[]}, - RH {id: 11, - sub: &[]}]}); - } - - pub fn lookup_item(&self, names: &[~str]) -> ast::node_id { - return match search_mod(self, &self.krate.node.module, 0, names) { - Some(id) => id, - None => { - fail!("no item found: `%s`", names.connect("::")); - } - }; - - fn search_mod(self: &Env, - m: &ast::Mod, - idx: uint, - names: &[~str]) -> Option { - assert!(idx < names.len()); - for item in m.items.iter() { - if self.tcx.sess.str_of(item.ident) == names[idx] { - return search(self, *item, idx+1, names); - } - } - return None; - } - - fn search(self: &Env, - it: @ast::Item, - idx: uint, - names: &[~str]) -> Option { - if idx == names.len() { - return Some(it.id); - } - - return match it.node { - ast::ItemConst(..) | ast::ItemFn(..) | - ast::ItemForeignMod(..) | ast::ItemTy(..) => { - None - } - - ast::ItemEnum(..) | ast::ItemStruct(..) | - ast::ItemTrait(..) | ast::ItemImpl(..) | - ast::ItemMac(..) => { - None - } - - ast::ItemMod(ref m) => { - search_mod(self, m, idx, names) - } - }; - } - } - - pub fn is_subtype(&self, a: ty::t, b: ty::t) -> bool { - match infer::can_mk_subty(self.infcx, a, b) { - Ok(_) => true, - Err(_) => false - } - } - - pub fn assert_subtype(&self, a: ty::t, b: ty::t) { - if !self.is_subtype(a, b) { - fail!("%s is not a subtype of %s, but it should be", - self.ty_to_str(a), - self.ty_to_str(b)); - } - } - - pub fn assert_not_subtype(&self, a: ty::t, b: ty::t) { - if self.is_subtype(a, b) { - fail!("%s is a subtype of %s, but it shouldn't be", - self.ty_to_str(a), - self.ty_to_str(b)); - } - } - - pub fn assert_strict_subtype(&self, a: ty::t, b: ty::t) { - self.assert_subtype(a, b); - self.assert_not_subtype(b, a); - } - - pub fn assert_eq(&self, a: ty::t, b: ty::t) { - self.assert_subtype(a, b); - self.assert_subtype(b, a); - } - - pub fn ty_to_str(&self, a: ty::t) -> ~str { - ty_to_str(self.tcx, a) - } - - pub fn t_fn(&self, input_tys: &[ty::t], output_ty: ty::t) -> ty::t { - let inputs = input_tys.map(|t| {mode: ast::expl(ast::by_copy), - ty: *t}); - ty::mk_fn(self.tcx, FnTyBase { - meta: FnMeta {purity: ast::ImpureFn, - proto: ast::ProtoBare, - onceness: ast::Many, - region: ty::ReStatic, - bounds: @~[]}, - sig: FnSig { - inputs: inputs, - output: output_ty, - variadic: false - } - }) - } - - pub fn t_int(&self) -> ty::t { - ty::mk_int(self.tcx) - } - - pub fn t_rptr_bound(&self, id: uint) -> ty::t { - ty::mk_imm_rptr(self.tcx, ty::re_bound(ty::BrAnon(id)), self.t_int()) - } - - pub fn t_rptr_scope(&self, id: ast::node_id) -> ty::t { - ty::mk_imm_rptr(self.tcx, ty::ReScope(id), self.t_int()) - } - - pub fn t_rptr_free(&self, nid: ast::node_id, id: uint) -> ty::t { - ty::mk_imm_rptr(self.tcx, - ty::ReFree(ty::FreeRegion {scope_id: nid, - bound_region: ty::BrAnon(id)}), - self.t_int()) - } - - pub fn t_rptr_static(&self) -> ty::t { - ty::mk_imm_rptr(self.tcx, ty::ReStatic, self.t_int()) - } - - pub fn lub() -> Lub { Lub(self.infcx.combine_fields(true, DUMMY_SP)) } - - pub fn glb() -> Glb { Glb(self.infcx.combine_fields(true, DUMMY_SP)) } - - pub fn resolve_regions(exp_count: uint) { - debug!("resolve_regions(%u)", exp_count); - - self.infcx.resolve_regions(); - if self.err_messages.len() != exp_count { - for msg in self.err_messages.iter() { - debug!("Error encountered: %s", *msg); - } - format!("resolving regions encountered %u errors but expected %u!", - self.err_messages.len(), - exp_count); - } - } - - /// Checks that `LUB(t1,t2) == t_lub` - pub fn check_lub(&self, t1: ty::t, t2: ty::t, t_lub: ty::t) { - match self.lub().tys(t1, t2) { - Err(e) => { - fail!("unexpected error computing LUB: %?", e) - } - Ok(t) => { - self.assert_eq(t, t_lub); - - // sanity check for good measure: - self.assert_subtype(t1, t); - self.assert_subtype(t2, t); - - self.resolve_regions(0); - } - } - } - - /// Checks that `GLB(t1,t2) == t_glb` - pub fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) { - debug!("check_glb(t1=%s, t2=%s, t_glb=%s)", - self.ty_to_str(t1), - self.ty_to_str(t2), - self.ty_to_str(t_glb)); - match self.glb().tys(t1, t2) { - Err(e) => { - fail!("unexpected error computing LUB: %?", e) - } - Ok(t) => { - self.assert_eq(t, t_glb); - - // sanity check for good measure: - self.assert_subtype(t, t1); - self.assert_subtype(t, t2); - - self.resolve_regions(0); - } - } - } - - /// Checks that `LUB(t1,t2)` is undefined - pub fn check_no_lub(&self, t1: ty::t, t2: ty::t) { - match self.lub().tys(t1, t2) { - Err(_) => {} - Ok(t) => { - fail!("unexpected success computing LUB: %?", self.ty_to_str(t)) - } - } - } - - /// Checks that `GLB(t1,t2)` is undefined - pub fn check_no_glb(&self, t1: ty::t, t2: ty::t) { - match self.glb().tys(t1, t2) { - Err(_) => {} - Ok(t) => { - fail!("unexpected success computing GLB: %?", self.ty_to_str(t)) - } - } - } -} - -#[test] -fn contravariant_region_ptr() { - let env = setup_env("contravariant_region_ptr", EMPTY_SOURCE_STR); - 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.assert_strict_subtype(t_rptr1, t_rptr10); -} - -#[test] -fn lub_bound_bound() { - let env = setup_env("lub_bound_bound", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_bound2 = env.t_rptr_bound(2); - env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_bound2], env.t_int()), - env.t_fn([t_rptr_bound1], env.t_int())); -} - -#[test] -fn lub_bound_free() { - let env = setup_env("lub_bound_free", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_free1 = env.t_rptr_free(0, 1); - env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_free1], env.t_int()), - env.t_fn([t_rptr_free1], env.t_int())); -} - -#[test] -fn lub_bound_static() { - let env = setup_env("lub_bound_static", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_static = env.t_rptr_static(); - env.check_lub(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_static], env.t_int()), - env.t_fn([t_rptr_static], env.t_int())); -} - -#[test] -fn lub_bound_bound_inverse_order() { - let env = setup_env("lub_bound_bound_inverse_order", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_bound2 = env.t_rptr_bound(2); - env.check_lub(env.t_fn([t_rptr_bound1, t_rptr_bound2], t_rptr_bound1), - env.t_fn([t_rptr_bound2, t_rptr_bound1], t_rptr_bound1), - env.t_fn([t_rptr_bound1, t_rptr_bound1], t_rptr_bound1)); -} - -#[test] -fn lub_free_free() { - let env = setup_env("lub_free_free", EMPTY_SOURCE_STR); - let t_rptr_free1 = env.t_rptr_free(0, 1); - let t_rptr_free2 = env.t_rptr_free(0, 2); - let t_rptr_static = env.t_rptr_static(); - env.check_lub(env.t_fn([t_rptr_free1], env.t_int()), - env.t_fn([t_rptr_free2], env.t_int()), - env.t_fn([t_rptr_static], env.t_int())); -} - -#[test] -fn lub_returning_scope() { - let env = setup_env("lub_returning_scope", EMPTY_SOURCE_STR); - let t_rptr_scope10 = env.t_rptr_scope(10); - let t_rptr_scope11 = env.t_rptr_scope(11); - env.check_no_lub(env.t_fn([], t_rptr_scope10), - env.t_fn([], t_rptr_scope11)); -} - -#[test] -fn glb_free_free_with_common_scope() { - let env = setup_env("glb_free_free", EMPTY_SOURCE_STR); - let t_rptr_free1 = env.t_rptr_free(0, 1); - let t_rptr_free2 = env.t_rptr_free(0, 2); - let t_rptr_scope = env.t_rptr_scope(0); - env.check_glb(env.t_fn([t_rptr_free1], env.t_int()), - env.t_fn([t_rptr_free2], env.t_int()), - env.t_fn([t_rptr_scope], env.t_int())); -} - -#[test] -fn glb_bound_bound() { - let env = setup_env("glb_bound_bound", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_bound2 = env.t_rptr_bound(2); - env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_bound2], env.t_int()), - env.t_fn([t_rptr_bound1], env.t_int())); -} - -#[test] -fn glb_bound_free() { - let env = setup_env("glb_bound_free", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_free1 = env.t_rptr_free(0, 1); - env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_free1], env.t_int()), - env.t_fn([t_rptr_bound1], env.t_int())); -} - -#[test] -fn glb_bound_static() { - let env = setup_env("glb_bound_static", EMPTY_SOURCE_STR); - let t_rptr_bound1 = env.t_rptr_bound(1); - let t_rptr_static = env.t_rptr_static(); - env.check_glb(env.t_fn([t_rptr_bound1], env.t_int()), - env.t_fn([t_rptr_static], env.t_int()), - env.t_fn([t_rptr_bound1], env.t_int())); -}