diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 2f252fc042a21..20371f63a3427 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -13,7 +13,6 @@ use back::link; use back::write; use driver::session::Session; use driver::config; -use front; use lint; use llvm::{ContextRef, ModuleRef}; use metadata::common::LinkMeta; @@ -166,7 +165,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) } if sess.show_span() { - front::show_span::run(sess, &krate); + syntax::show_span::run(sess.diagnostic(), &krate); } krate @@ -194,11 +193,29 @@ pub fn phase_2_configure_and_expand(sess: &Session, *sess.crate_metadata.borrow_mut() = collect_crate_metadata(sess, krate.attrs.as_slice()); - time(time_passes, "gated feature checking", (), |_| - front::feature_gate::check_crate(sess, &krate)); + time(time_passes, "gated feature checking", (), |_| { + let (features, unknown_features) = + syntax::feature_gate::check_crate(&sess.parse_sess.span_diagnostic, &krate); + + for uf in unknown_features.iter() { + sess.add_lint(lint::builtin::UNKNOWN_FEATURES, + ast::CRATE_NODE_ID, + *uf, + "unknown feature".to_string()); + } + + sess.abort_if_errors(); + *sess.features.borrow_mut() = features; + }); + + let any_exe = sess.crate_types.borrow().iter().any(|ty| { + *ty == config::CrateTypeExecutable + }); krate = time(time_passes, "crate injection", krate, |krate| - front::std_inject::maybe_inject_crates_ref(sess, krate)); + syntax::std_inject::maybe_inject_crates_ref(krate, + sess.opts.alt_std_name.clone(), + any_exe)); // strip before expansion to allow macros to depend on // configuration variables e.g/ in @@ -209,7 +226,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, // baz! should not use this definition unless foo is enabled. krate = time(time_passes, "configuration 1", krate, |krate| - front::config::strip_unconfigured_items(krate)); + syntax::config::strip_unconfigured_items(krate)); let mut addl_plugins = Some(addl_plugins); let Plugins { macros, registrars } @@ -219,7 +236,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, let mut registry = Registry::new(&krate); time(time_passes, "plugin registration", (), |_| { - if sess.features.rustc_diagnostic_macros.get() { + if sess.features.borrow().rustc_diagnostic_macros { registry.register_macro("__diagnostic_used", diagnostics::plugin::expand_diagnostic_used); registry.register_macro("__register_diagnostic", @@ -271,7 +288,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); } let cfg = syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: sess.features.default_type_params.get(), + deriving_hash_type_parameter: sess.features.borrow().default_type_params, crate_name: crate_name.to_string(), }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, @@ -290,13 +307,16 @@ pub fn phase_2_configure_and_expand(sess: &Session, // strip again, in case expansion added anything with a #[cfg]. krate = time(time_passes, "configuration 2", krate, |krate| - front::config::strip_unconfigured_items(krate)); + syntax::config::strip_unconfigured_items(krate)); krate = time(time_passes, "maybe building test harness", krate, |krate| - front::test::modify_for_testing(sess, krate)); + syntax::test::modify_for_testing(&sess.parse_sess, + &sess.opts.cfg, + krate, + sess.diagnostic())); krate = time(time_passes, "prelude injection", krate, |krate| - front::std_inject::maybe_inject_prelude(sess, krate)); + syntax::std_inject::maybe_inject_prelude(krate)); time(time_passes, "checking that all macro invocations are gone", &krate, |krate| syntax::ext::expand::check_for_macros(&sess.parse_sess, krate)); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 6f020184b336d..d7ed5d3e1ffa4 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -11,7 +11,6 @@ use driver::config; use driver::driver; -use front; use metadata::cstore::CStore; use metadata::filesearch; use lint; @@ -21,6 +20,7 @@ use syntax::ast::NodeId; use syntax::codemap::Span; use syntax::diagnostic; use syntax::diagnostics; +use syntax::feature_gate; use syntax::parse; use syntax::parse::token; use syntax::parse::ParseSess; @@ -47,10 +47,9 @@ pub struct Session { pub working_dir: Path, pub lint_store: RefCell, pub lints: RefCell>>, - pub node_id: Cell, pub crate_types: RefCell>, pub crate_metadata: RefCell>, - pub features: front::feature_gate::Features, + pub features: RefCell, /// The maximum recursion limit for potentially infinitely recursive /// operations such as auto-dereference and monomorphization. @@ -129,17 +128,10 @@ impl Session { lints.insert(id, vec!((lint_id, sp, msg))); } pub fn next_node_id(&self) -> ast::NodeId { - self.reserve_node_ids(1) + self.parse_sess.next_node_id() } pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { - let v = self.node_id.get(); - - match v.checked_add(&count) { - Some(next) => { self.node_id.set(next); } - None => self.bug("Input too large, ran out of node ids!") - } - - v + self.parse_sess.reserve_node_ids(count) } pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler { &self.parse_sess.span_diagnostic @@ -251,10 +243,9 @@ pub fn build_session_(sopts: config::Options, working_dir: os::getcwd(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap::new()), - node_id: Cell::new(1), crate_types: RefCell::new(Vec::new()), crate_metadata: RefCell::new(Vec::new()), - features: front::feature_gate::Features::new(), + features: RefCell::new(feature_gate::Features::new()), recursion_limit: Cell::new(64), }; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index af3d19c4d2d40..81234f36ade50 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -116,14 +116,6 @@ pub mod middle { pub mod weak_lang_items; } -pub mod front { - pub mod config; - pub mod test; - pub mod std_inject; - pub mod feature_gate; - pub mod show_span; -} - pub mod metadata; pub mod driver; diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ded4883350ff2..d4fe3c265f518 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -2811,7 +2811,7 @@ impl<'a> Resolver<'a> { import_span: Span, name: Name, namespace: Namespace) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2837,7 +2837,7 @@ impl<'a> Resolver<'a> { &mut ImportResolution, import_span: Span, name: Name) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2919,7 +2919,7 @@ impl<'a> Resolver<'a> { module: &Module, name: Name, span: Span) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } @@ -2937,7 +2937,7 @@ impl<'a> Resolver<'a> { module: &Module, name: Name, span: Span) { - if self.session.features.import_shadowing.get() { + if self.session.features.borrow().import_shadowing { return } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index cb449f80ed4a4..c46e95cf045f5 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -235,7 +235,7 @@ fn ast_path_substs<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } if supplied_ty_param_count > required_ty_param_count - && !this.tcx().sess.features.default_type_params.get() { + && !this.tcx().sess.features.borrow().default_type_params { span_err!(this.tcx().sess, path.span, E0108, "default type parameters are experimental and possibly buggy"); span_note!(this.tcx().sess, path.span, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 20fe8186adf40..12905763f522b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2131,7 +2131,7 @@ fn try_overloaded_call(fcx: &FnCtxt, fcx.inh.method_map.borrow_mut().insert(method_call, method_callee); write_call(fcx, call_expression, output_type); - if !fcx.tcx().sess.features.overloaded_calls.get() { + if !fcx.tcx().sess.features.borrow().overloaded_calls { span_err!(fcx.tcx().sess, call_expression.span, E0056, "overloaded calls are experimental"); span_note!(fcx.tcx().sess, call_expression.span, diff --git a/src/librustc/front/config.rs b/src/libsyntax/config.rs similarity index 98% rename from src/librustc/front/config.rs rename to src/libsyntax/config.rs index 2e05cb054e886..cb96cd911b5c6 100644 --- a/src/librustc/front/config.rs +++ b/src/libsyntax/config.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::fold::Folder; -use syntax::{ast, fold, attr}; -use syntax::codemap::Spanned; -use syntax::ptr::P; +use fold::Folder; +use {ast, fold, attr}; +use codemap::Spanned; +use ptr::P; /// A folder that strips out items that do not belong in the current /// configuration. diff --git a/src/librustc/front/feature_gate.rs b/src/libsyntax/feature_gate.rs similarity index 87% rename from src/librustc/front/feature_gate.rs rename to src/libsyntax/feature_gate.rs index 13a40aba93078..e22e55193fca3 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -18,21 +18,17 @@ //! Features are enabled in programs via the crate-level attributes of //! `#![feature(...)]` with a comma-separated list of features. -use lint; +use abi::RustIntrinsic; +use ast::NodeId; +use ast; +use attr; +use attr::AttrMetaMethods; +use codemap::Span; +use diagnostic::SpanHandler; +use visit; +use visit::Visitor; +use parse::token; -use syntax::abi::RustIntrinsic; -use syntax::ast::NodeId; -use syntax::ast; -use syntax::attr; -use syntax::attr::AttrMetaMethods; -use syntax::codemap::Span; -use syntax::visit; -use syntax::visit::Visitor; -use syntax::parse::token; - -use driver::session::Session; - -use std::cell::Cell; use std::slice; /// This is a list of all known features since the beginning of time. This list @@ -99,35 +95,35 @@ enum Status { /// A set of features to be used by later passes. pub struct Features { - pub default_type_params: Cell, - pub overloaded_calls: Cell, - pub rustc_diagnostic_macros: Cell, - pub import_shadowing: Cell, + pub default_type_params: bool, + pub overloaded_calls: bool, + pub rustc_diagnostic_macros: bool, + pub import_shadowing: bool, } impl Features { pub fn new() -> Features { Features { - default_type_params: Cell::new(false), - overloaded_calls: Cell::new(false), - rustc_diagnostic_macros: Cell::new(false), - import_shadowing: Cell::new(false), + default_type_params: false, + overloaded_calls: false, + rustc_diagnostic_macros: false, + import_shadowing: false, } } } struct Context<'a> { features: Vec<&'static str>, - sess: &'a Session, + span_handler: &'a SpanHandler, } impl<'a> Context<'a> { fn gate_feature(&self, feature: &str, span: Span, explain: &str) { if !self.has_feature(feature) { - self.sess.span_err(span, explain); - self.sess.span_note(span, format!("add #![feature({})] to the \ - crate attributes to enable", - feature).as_slice()); + self.span_handler.span_err(span, explain); + self.span_handler.span_note(span, format!("add #![feature({})] to the \ + crate attributes to enable", + feature).as_slice()); } } @@ -404,12 +400,14 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { } } -pub fn check_crate(sess: &Session, krate: &ast::Crate) { +pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, Vec) { let mut cx = Context { features: Vec::new(), - sess: sess, + span_handler: span_handler, }; + let mut unknown_features = Vec::new(); + for attr in krate.attrs.iter() { if !attr.check_name("feature") { continue @@ -417,17 +415,17 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { match attr.meta_item_list() { None => { - sess.span_err(attr.span, "malformed feature attribute, \ - expected #![feature(...)]"); + span_handler.span_err(attr.span, "malformed feature attribute, \ + expected #![feature(...)]"); } Some(list) => { for mi in list.iter() { let name = match mi.node { ast::MetaWord(ref word) => (*word).clone(), _ => { - sess.span_err(mi.span, - "malformed feature, expected just \ - one word"); + span_handler.span_err(mi.span, + "malformed feature, expected just \ + one word"); continue } }; @@ -435,17 +433,14 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { .find(|& &(n, _)| name.equiv(&n)) { Some(&(name, Active)) => { cx.features.push(name); } Some(&(_, Removed)) => { - sess.span_err(mi.span, "feature has been removed"); + span_handler.span_err(mi.span, "feature has been removed"); } Some(&(_, Accepted)) => { - sess.span_warn(mi.span, "feature has been added to Rust, \ - directive not necessary"); + span_handler.span_warn(mi.span, "feature has been added to Rust, \ + directive not necessary"); } None => { - sess.add_lint(lint::builtin::UNKNOWN_FEATURES, - ast::CRATE_NODE_ID, - mi.span, - "unknown feature".to_string()); + unknown_features.push(mi.span); } } } @@ -455,11 +450,12 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) { visit::walk_crate(&mut cx, krate); - sess.abort_if_errors(); - - sess.features.default_type_params.set(cx.has_feature("default_type_params")); - sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls")); - sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros")); - sess.features.import_shadowing.set(cx.has_feature("import_shadowing")); + (Features { + default_type_params: cx.has_feature("default_type_params"), + overloaded_calls: cx.has_feature("overloaded_calls"), + rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"), + import_shadowing: cx.has_feature("import_shadowing"), + }, + unknown_features) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 146b5a5b34865..457d77efb708e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -59,12 +59,17 @@ pub mod ast_map; pub mod ast_util; pub mod attr; pub mod codemap; +pub mod config; pub mod crateid; pub mod diagnostic; +pub mod feature_gate; pub mod fold; pub mod owned_slice; pub mod parse; pub mod ptr; +pub mod show_span; +pub mod std_inject; +pub mod test; pub mod visit; pub mod print { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index e5b6359000b6c..d73cb2116941a 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -17,7 +17,7 @@ use parse::attr::ParserAttr; use parse::parser::Parser; use ptr::P; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::io::File; use std::rc::Rc; use std::str; @@ -37,12 +37,14 @@ pub struct ParseSess { pub span_diagnostic: SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions included_mod_stack: RefCell>, + pub node_id: Cell, } pub fn new_parse_sess() -> ParseSess { ParseSess { span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()), included_mod_stack: RefCell::new(Vec::new()), + node_id: Cell::new(1), } } @@ -50,6 +52,23 @@ pub fn new_parse_sess_special_handler(sh: SpanHandler) -> ParseSess { ParseSess { span_diagnostic: sh, included_mod_stack: RefCell::new(Vec::new()), + node_id: Cell::new(1), + } +} + +impl ParseSess { + pub fn next_node_id(&self) -> ast::NodeId { + self.reserve_node_ids(1) + } + pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { + let v = self.node_id.get(); + + match v.checked_add(&count) { + Some(next) => { self.node_id.set(next); } + None => fail!("Input too large, ran out of node ids!") + } + + v } } diff --git a/src/librustc/front/show_span.rs b/src/libsyntax/show_span.rs similarity index 74% rename from src/librustc/front/show_span.rs rename to src/libsyntax/show_span.rs index df0b02261b149..354ba854b101a 100644 --- a/src/librustc/front/show_span.rs +++ b/src/libsyntax/show_span.rs @@ -13,19 +13,18 @@ //! This module shows spans for all expressions in the crate //! to help with compiler debugging. -use syntax::ast; -use syntax::visit; -use syntax::visit::Visitor; - -use driver::session::Session; +use ast; +use diagnostic; +use visit; +use visit::Visitor; struct ShowSpanVisitor<'a> { - sess: &'a Session + span_diagnostic: &'a diagnostic::SpanHandler, } impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> { fn visit_expr(&mut self, e: &ast::Expr) { - self.sess.span_note(e.span, "expression"); + self.span_diagnostic.span_note(e.span, "expression"); visit::walk_expr(self, e); } @@ -34,7 +33,7 @@ impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> { } } -pub fn run(sess: &Session, krate: &ast::Crate) { - let mut v = ShowSpanVisitor { sess: sess }; +pub fn run(span_diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate) { + let mut v = ShowSpanVisitor { span_diagnostic: span_diagnostic }; visit::walk_crate(&mut v, krate); } diff --git a/src/librustc/front/std_inject.rs b/src/libsyntax/std_inject.rs similarity index 87% rename from src/librustc/front/std_inject.rs rename to src/libsyntax/std_inject.rs index 748641ba70c2b..8a7e14643c1a7 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -8,36 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use driver::config; -use driver::session::Session; - -use syntax::ast; -use syntax::attr; -use syntax::codemap::DUMMY_SP; -use syntax::codemap; -use syntax::fold::Folder; -use syntax::fold; -use syntax::owned_slice::OwnedSlice; -use syntax::parse::token::InternedString; -use syntax::parse::token::special_idents; -use syntax::parse::token; -use syntax::ptr::P; -use syntax::util::small_vector::SmallVector; +use ast; +use attr; +use codemap::DUMMY_SP; +use codemap; +use fold::Folder; +use fold; +use owned_slice::OwnedSlice; +use parse::token::InternedString; +use parse::token::special_idents; +use parse::token; +use ptr::P; +use util::small_vector::SmallVector; use std::mem; -pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate) +pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option, any_exe: bool) -> ast::Crate { if use_std(&krate) { - inject_crates_ref(sess, krate) + inject_crates_ref(krate, alt_std_name, any_exe) } else { krate } } -pub fn maybe_inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate { +pub fn maybe_inject_prelude(krate: ast::Crate) -> ast::Crate { if use_std(&krate) { - inject_prelude(sess, krate) + inject_prelude(krate) } else { krate } @@ -56,14 +53,15 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool { } struct StandardLibraryInjector<'a> { - sess: &'a Session, + alt_std_name: Option, + any_exe: bool, } impl<'a> fold::Folder for StandardLibraryInjector<'a> { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { // The name to use in `extern crate "name" as std;` - let actual_crate_name = match self.sess.opts.alt_std_name { + let actual_crate_name = match self.alt_std_name { Some(ref s) => token::intern_and_get_ident(s.as_slice()), None => token::intern_and_get_ident("std"), }; @@ -83,10 +81,7 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { span: DUMMY_SP }); - let any_exe = self.sess.crate_types.borrow().iter().any(|ty| { - *ty == config::CrateTypeExecutable - }); - if use_start(&krate) && any_exe { + if use_start(&krate) && self.any_exe { let visible_rt_name = "rt"; let actual_rt_name = "native"; // Gensym the ident so it can't be named @@ -124,9 +119,12 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { } } -fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate { +fn inject_crates_ref(krate: ast::Crate, + alt_std_name: Option, + any_exe: bool) -> ast::Crate { let mut fold = StandardLibraryInjector { - sess: sess, + alt_std_name: alt_std_name, + any_exe: any_exe, }; fold.fold_crate(krate) } @@ -231,7 +229,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> { } } -fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate { +fn inject_prelude(krate: ast::Crate) -> ast::Crate { let mut fold = PreludeInjector; fold.fold_crate(krate) } diff --git a/src/librustc/front/test.rs b/src/libsyntax/test.rs similarity index 92% rename from src/librustc/front/test.rs rename to src/libsyntax/test.rs index 737fe748340e6..f0e697127149f 100644 --- a/src/librustc/front/test.rs +++ b/src/libsyntax/test.rs @@ -13,29 +13,29 @@ #![allow(dead_code)] #![allow(unused_imports)] -use driver::session::Session; -use front::config; - +use std::gc::{Gc, GC}; use std::slice; use std::mem; use std::vec; -use syntax::{ast, ast_util}; -use syntax::ast_util::*; -use syntax::attr::AttrMetaMethods; -use syntax::attr; -use syntax::codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; -use syntax::codemap; -use syntax::ext::base::ExtCtxt; -use syntax::ext::build::AstBuilder; -use syntax::ext::expand::ExpansionConfig; -use syntax::fold::{Folder, MoveMap}; -use syntax::fold; -use syntax::owned_slice::OwnedSlice; -use syntax::parse::token::InternedString; -use syntax::parse::token; -use syntax::print::pprust; -use syntax::ptr::P; -use syntax::util::small_vector::SmallVector; +use ast_util::*; +use attr::AttrMetaMethods; +use attr; +use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; +use codemap; +use diagnostic; +use config; +use ext::base::ExtCtxt; +use ext::build::AstBuilder; +use ext::expand::ExpansionConfig; +use fold::{Folder, MoveMap}; +use fold; +use owned_slice::OwnedSlice; +use parse::token::InternedString; +use parse::{token, ParseSess}; +use print::pprust; +use {ast, ast_util}; +use ptr::P; +use util::small_vector::SmallVector; struct Test { span: Span, @@ -46,7 +46,8 @@ struct Test { } struct TestCtxt<'a> { - sess: &'a Session, + sess: &'a ParseSess, + span_diagnostic: &'a diagnostic::SpanHandler, path: Vec, ext_cx: ExtCtxt<'a>, testfns: Vec, @@ -60,8 +61,10 @@ struct TestCtxt<'a> { // Traverse the crate, collecting all the test functions, eliding any // existing main functions, and synthesizing a main test harness -pub fn modify_for_testing(sess: &Session, - krate: ast::Crate) -> ast::Crate { +pub fn modify_for_testing(sess: &ParseSess, + cfg: &ast::CrateConfig, + krate: ast::Crate, + span_diagnostic: &diagnostic::SpanHandler) -> ast::Crate { // We generate the test harness when building in the 'test' // configuration, either with the '--test' or '--cfg test' // command line options. @@ -76,7 +79,7 @@ pub fn modify_for_testing(sess: &Session, "reexport_test_harness_main"); if should_test { - generate_test_harness(sess, reexport_test_harness_main, krate) + generate_test_harness(sess, reexport_test_harness_main, krate, cfg, span_diagnostic) } else { strip_test_functions(krate) } @@ -113,8 +116,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) { match i.node { ast::ItemFn(_, ast::UnsafeFn, _, _, _) => { - let sess = self.cx.sess; - sess.span_fatal(i.span, + let diag = self.cx.span_diagnostic; + diag.span_fatal(i.span, "unsafe functions cannot be used for \ tests"); } @@ -223,12 +226,15 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec, (it, sym) } -fn generate_test_harness(sess: &Session, +fn generate_test_harness(sess: &ParseSess, reexport_test_harness_main: Option, - krate: ast::Crate) -> ast::Crate { + krate: ast::Crate, + cfg: &ast::CrateConfig, + sd: &diagnostic::SpanHandler) -> ast::Crate { let mut cx: TestCtxt = TestCtxt { sess: sess, - ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(), + span_diagnostic: sd, + ext_cx: ExtCtxt::new(sess, cfg.clone(), ExpansionConfig { deriving_hash_type_parameter: false, crate_name: "test".to_string(), @@ -288,8 +294,8 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { } if has_test_attr && !has_test_signature(i) { - let sess = cx.sess; - sess.span_err( + let diag = cx.span_diagnostic; + diag.span_err( i.span, "functions used as tests must have signature fn() -> ()." ); @@ -320,8 +326,8 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { } if has_bench_attr && !has_test_signature(i) { - let sess = cx.sess; - sess.span_err(i.span, "functions used as benches must have signature \ + let diag = cx.span_diagnostic; + diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> ()`"); } @@ -547,9 +553,8 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { let mut visible_path = match cx.toplevel_reexport { Some(id) => vec![id], None => { - cx.sess.bug( - "expected to find top-level re-export name, but found None" - ); + let diag = cx.span_diagnostic; + diag.handler.bug("expected to find top-level re-export name, but found None"); } }; visible_path.extend(path.into_iter());