diff options
| -rw-r--r-- | src/librustc_driver/test.rs | 382 |
1 files changed, 219 insertions, 163 deletions
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fec69d91d8c..f18f40bf7a1 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -14,29 +14,29 @@ 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, SuppressRegionErrors}; +use errors; +use errors::emitter::Emitter; +use errors::{DiagnosticBuilder, Level}; +use rustc::hir::map as hir_map; 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::infer::{self, InferOk, InferResult, SuppressRegionErrors}; +use rustc::middle::region; use rustc::session::config::{OutputFilenames, OutputTypes}; +use rustc::session::{self, config}; +use rustc::traits::ObligationCause; +use rustc::ty::query::OnDiskCache; +use rustc::ty::subst::Subst; +use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::sync::{self, Lrc}; +use rustc_lint; +use rustc_metadata::cstore::CStore; +use rustc_resolve::MakeGlobMap; +use rustc_target::spec::abi::Abi; use syntax; use syntax::ast; -use rustc_target::spec::abi::Abi; -use syntax::source_map::{SourceMap, FilePathMapping, FileName}; -use errors; -use errors::emitter::Emitter; -use errors::{Level, DiagnosticBuilder}; use syntax::feature_gate::UnstableFeatures; +use syntax::source_map::{FileName, FilePathMapping, SourceMap}; use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; @@ -90,13 +90,15 @@ impl Emitter for ExpectErrorEmitter { 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()) + ( + 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) +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(); @@ -113,34 +115,41 @@ 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) + 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(SourceMap::new(FilePathMapping::empty()))); + let sess = session::build_session_( + options, + None, + diagnostic_handler, + Lrc::new(SourceMap::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 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(); @@ -155,32 +164,39 @@ fn test_env_with_pool<F>( 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.source_map()), - "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, + TyCtxt::create_and_enter( + &sess, + &cstore, + ty::query::Providers::default(), + ty::query::Providers::default(), + &arenas, + resolutions, + hir_map, + OnDiskCache::new_empty(sess.source_map()), + "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, + ®ion_scope_tree, + &outlives_env, + SuppressRegionErrors::default(), + ); + assert_eq!(tcx.sess.err_count(), expected_err_count); }); - 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, ®ion_scope_tree, &outlives_env, SuppressRegionErrors::default()); - assert_eq!(tcx.sess.err_count(), expected_err_count); - }); - }); + }, + ); } fn d1() -> ty::DebruijnIndex { @@ -196,9 +212,15 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { self.infcx.tcx } - pub fn create_region_hierarchy(&mut self, rh: &RH, - parent: (region::Scope, region::ScopeDepth)) { - let me = region::Scope { id: rh.id, data: region::ScopeData::Node }; + pub fn create_region_hierarchy( + &mut self, + rh: &RH, + parent: (region::Scope, region::ScopeDepth), + ) { + let me = region::Scope { + id: rh.id, + data: region::ScopeData::Node, + }; 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)); @@ -211,20 +233,25 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { let dscope = region::Scope { id: hir::ItemLocalId(1), - data: region::ScopeData::Destruction + data: region::ScopeData::Destruction, }; 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: &[], + self.create_region_hierarchy( + &RH { + id: hir::ItemLocalId(1), + sub: &[ + RH { + id: hir::ItemLocalId(10), + sub: &[], + }, + RH { + id: hir::ItemLocalId(11), + sub: &[], + }, + ], }, - RH { - id: hir::ItemLocalId(11), - sub: &[], - }], - }, (dscope, 1)); + (dscope, 1), + ); } #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now @@ -236,11 +263,12 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } }; - fn search_mod(this: &Env, - m: &hir::Mod, - idx: usize, - names: &[String]) - -> Option<ast::NodeId> { + 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); @@ -257,22 +285,22 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } 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::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), }; @@ -280,7 +308,10 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn make_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - match self.infcx.at(&ObligationCause::dummy(), self.param_env).sub(a, b) { + match self.infcx + .at(&ObligationCause::dummy(), self.param_env) + .sub(a, b) + { Ok(_) => true, Err(ref e) => panic!("Encountered error: {}", e), } @@ -302,13 +333,15 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } 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 - ))) + 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> { @@ -321,23 +354,30 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { 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()) + 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, - })) + 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 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> { @@ -349,10 +389,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { 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> { + 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) } @@ -360,9 +401,11 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> { let r = ty::ReScope(region::Scope { id: hir::ItemLocalId(id), - data: region::ScopeData::Node + data: region::ScopeData::Node, }); - self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize) + 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> { @@ -378,14 +421,19 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> InferResult<'tcx, ()> { - self.infcx.at(&ObligationCause::dummy(), self.param_env).sub(t1, t2) + 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: () }) => { + Ok(InferOk { + obligations, + value: (), + }) => { // None of these tests should require nested obligations: assert!(obligations.is_empty()); } @@ -445,8 +493,10 @@ fn sub_free_bound_false() { 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)); + env.check_not_sub( + env.t_fn(&[t_rptr_free1], env.tcx().types.isize), + env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), + ); }) } @@ -462,8 +512,10 @@ fn sub_bound_free_true() { 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)); + env.check_sub( + env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), + env.t_fn(&[t_rptr_free1], env.tcx().types.isize), + ); }) } @@ -476,10 +528,13 @@ fn sub_free_bound_false_infer() { //! 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_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)); + env.check_not_sub( + env.t_fn(&[t_infer1], env.tcx().types.isize), + env.t_fn(&[t_rptr_bound1], env.tcx().types.isize), + ); }) } @@ -487,7 +542,6 @@ fn sub_free_bound_false_infer() { /// This requires adjusting the Debruijn index. #[test] fn subst_ty_renumber_bound() { - test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { // Situation: // Theta = [A -> &'a foo] @@ -509,11 +563,10 @@ fn subst_ty_renumber_bound() { 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); + debug!( + "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}", + t_source, substs, t_substituted, t_expected + ); assert_eq!(t_substituted, t_expected); }) @@ -546,11 +599,10 @@ fn subst_ty_renumber_some_bounds() { 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); + debug!( + "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}", + t_source, substs, t_substituted, t_expected + ); assert_eq!(t_substituted, t_expected); }) @@ -559,7 +611,6 @@ fn subst_ty_renumber_some_bounds() { /// 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] @@ -608,11 +659,10 @@ fn subst_region_renumber_region() { 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); + debug!( + "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}", + t_source, substs, t_substituted, t_expected + ); assert_eq!(t_substituted, t_expected); }) @@ -627,9 +677,13 @@ fn walk_ty() { 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]); + 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 + ] + ); }) } @@ -644,14 +698,16 @@ fn walk_ty_skip_subtree() { // 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)]; + 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(); |
