commit
88cb454b91
@ -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));
|
||||
|
@ -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<lint::LintStore>,
|
||||
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
|
||||
pub node_id: Cell<ast::NodeId>,
|
||||
pub crate_types: RefCell<Vec<config::CrateType>>,
|
||||
pub crate_metadata: RefCell<Vec<String>>,
|
||||
pub features: front::feature_gate::Features,
|
||||
pub features: RefCell<feature_gate::Features>,
|
||||
|
||||
/// 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),
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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.
|
@ -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<bool>,
|
||||
pub overloaded_calls: Cell<bool>,
|
||||
pub rustc_diagnostic_macros: Cell<bool>,
|
||||
pub import_shadowing: Cell<bool>,
|
||||
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<Span>) {
|
||||
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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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<Vec<Path>>,
|
||||
pub node_id: Cell<ast::NodeId>,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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<String>, 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<String>,
|
||||
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<String>,
|
||||
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)
|
||||
}
|
@ -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<ast::Ident>,
|
||||
ext_cx: ExtCtxt<'a>,
|
||||
testfns: Vec<Test>,
|
||||
@ -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<ast::Ident>,
|
||||
(it, sym)
|
||||
}
|
||||
|
||||
fn generate_test_harness(sess: &Session,
|
||||
fn generate_test_harness(sess: &ParseSess,
|
||||
reexport_test_harness_main: Option<InternedString>,
|
||||
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<ast::Expr> {
|
||||
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());
|
Loading…
x
Reference in New Issue
Block a user