let say = |s: &str| {
match (sp, sess) {
(_, None) => panic!("{}", s),
- (Some(sp), Some(sess)) => sess.span_err(sp, s),
- (None, Some(sess)) => sess.err(s),
+ (Some(sp), Some(sess)) => sess.span_fatal(sp, s),
+ (None, Some(sess)) => sess.fatal(s),
}
};
if s.is_empty() {
if c == '_' { continue }
say(&format!("invalid character `{}` in crate name: `{}`", c, s));
}
- match sess {
- Some(sess) => sess.abort_if_errors(),
- None => {}
- }
}
/// A dummy crate store that does not support any non-local crates,
collector.collect(krate);
let LanguageItemCollector { mut items, .. } = collector;
weak_lang_items::check_crate(krate, session, &mut items);
- session.abort_if_errors();
items
}
pub fn abort_if_errors(&self) {
self.diagnostic().abort_if_errors();
}
- pub fn abort_if_new_errors<F>(&self, mut f: F)
- where F: FnMut()
+ pub fn abort_if_new_errors<F, T>(&self, f: F) -> T
+ where F: FnOnce() -> T
{
let count = self.err_count();
- f();
+ let result = f();
if self.err_count() > count {
self.abort_if_errors();
}
+ result
}
pub fn span_warn(&self, sp: Span, msg: &str) {
self.diagnostic().span_warn(sp, msg)
let state = $make_state;
(control.$point.callback)(state);
- $tsess.abort_if_errors();
if control.$point.stop == Compilation::Stop {
return;
}
});
time(time_passes, "gated macro checking", || {
- let features = syntax::feature_gate::check_crate_macros(sess.codemap(),
- &sess.parse_sess.span_diagnostic,
- &krate);
-
- // these need to be set "early" so that expansion sees `quote` if enabled.
- *sess.features.borrow_mut() = features;
- sess.abort_if_errors();
+ sess.abort_if_new_errors(|| {
+ let features =
+ syntax::feature_gate::check_crate_macros(sess.codemap(),
+ &sess.parse_sess.span_diagnostic,
+ &krate);
+
+ // these need to be set "early" so that expansion sees `quote` if enabled.
+ *sess.features.borrow_mut() = features;
+ });
});
let Registry { syntax_exts, early_lint_passes, late_lint_passes, lint_groups,
llvm_passes, attributes, .. } = registry;
- {
+ sess.abort_if_new_errors(|| {
let mut ls = sess.lint_store.borrow_mut();
for pass in early_lint_passes {
ls.register_early_pass(Some(sess), true, pass);
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
*sess.plugin_attributes.borrow_mut() = attributes.clone();
- }
+ });
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
super::describe_lints(&*sess.lint_store.borrow(), true);
return None;
}
- sess.lint_store.borrow_mut().process_command_line(sess);
-
- // Abort if there are errors from lint processing or a plugin registrar.
- sess.abort_if_errors();
+ sess.abort_if_new_errors(|| sess.lint_store.borrow_mut().process_command_line(sess));
krate = time(time_passes, "expansion", || {
// Windows dlls do not have rpaths, so they don't know how to find their
// much as possible (e.g. help the programmer avoid platform
// specific differences)
time(time_passes, "complete gated feature checking 1", || {
- let features = syntax::feature_gate::check_crate(sess.codemap(),
- &sess.parse_sess.span_diagnostic,
- &krate,
- &attributes,
- sess.opts.unstable_features);
- *sess.features.borrow_mut() = features;
- sess.abort_if_errors();
+ sess.abort_if_new_errors(|| {
+ let features = syntax::feature_gate::check_crate(sess.codemap(),
+ &sess.parse_sess.span_diagnostic,
+ &krate,
+ &attributes,
+ sess.opts.unstable_features);
+ *sess.features.borrow_mut() = features;
+ });
});
// JBC: make CFG processing part of expansion to avoid this problem:
// later, to make sure we've got everything (e.g. configuration
// can insert new attributes via `cfg_attr`)
time(time_passes, "complete gated feature checking 2", || {
- let features = syntax::feature_gate::check_crate(sess.codemap(),
- &sess.parse_sess.span_diagnostic,
- &krate,
- &attributes,
- sess.opts.unstable_features);
- *sess.features.borrow_mut() = features;
- sess.abort_if_errors();
+ sess.abort_if_new_errors(|| {
+ let features = syntax::feature_gate::check_crate(sess.codemap(),
+ &sess.parse_sess.span_diagnostic,
+ &krate,
+ &attributes,
+ sess.opts.unstable_features);
+ *sess.features.borrow_mut() = features;
+ });
});
time(time_passes,
"external crate/lib resolution",
|| LocalCrateReader::new(sess, cstore, &hir_map).read_crates(krate));
- let lang_items = time(time_passes,
- "language item collection",
- || middle::lang_items::collect_language_items(&sess, &hir_map));
+ let lang_items = time(time_passes, "language item collection", || {
+ sess.abort_if_new_errors(|| {
+ middle::lang_items::collect_language_items(&sess, &hir_map)
+ })
+ });
let resolve::CrateMap {
def_map,
metadata: &MetadataBlob) {
let crate_rustc_version = decoder::crate_rustc_version(metadata.as_slice());
if crate_rustc_version != Some(rustc_version()) {
- span_err!(self.sess, span, E0514,
- "the crate `{}` has been compiled with {}, which is \
- incompatible with this version of rustc",
- name,
- crate_rustc_version
- .as_ref().map(|s|&**s)
- .unwrap_or("an old version of rustc")
+ span_fatal!(self.sess, span, E0514,
+ "the crate `{}` has been compiled with {}, which is \
+ incompatible with this version of rustc",
+ name,
+ crate_rustc_version
+ .as_ref().map(|s|&**s)
+ .unwrap_or("an old version of rustc")
);
- self.sess.abort_if_errors();
}
}
}
};
let span = mk_sp(lo, p.last_span.hi);
- p.abort_if_errors();
// Mark the attrs as used
for attr in &attrs {
name,
config::host_triple(),
self.sess.opts.target_triple);
- span_err!(self.sess, span, E0456, "{}", &message[..]);
- self.sess.abort_if_errors();
+ span_fatal!(self.sess, span, E0456, "{}", &message[..]);
}
let registrar =
use syntax::codemap::Span;
pub fn check_crate(sess: &Session, krate: &ast::Crate) {
- visit::walk_crate(&mut CheckConstFn{ sess: sess }, krate);
- sess.abort_if_errors();
+ sess.abort_if_new_errors(|| {
+ visit::walk_crate(&mut CheckConstFn{ sess: sess }, krate);
+ });
}
struct CheckConstFn<'a> {
resolver.callback = callback;
build_reduced_graph::build_reduced_graph(&mut resolver, krate);
- session.abort_if_errors();
resolve_imports::resolve_imports(&mut resolver);
- session.abort_if_errors();
resolver
}
pub enum Level {
Bug,
Fatal,
+ // An error which while not immediately fatal, should stop the compiler
+ // progressing beyond the current phase.
+ PhaseFatal,
Error,
Warning,
Note,
impl Level {
fn color(self) -> term::color::Color {
match self {
- Bug | Fatal | Error => term::color::BRIGHT_RED,
+ Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
Warning => term::color::BRIGHT_YELLOW,
Note => term::color::BRIGHT_GREEN,
Help => term::color::BRIGHT_CYAN,
fn to_str(self) -> &'static str {
match self {
Bug => "error: internal compiler error",
- Fatal | Error => "error",
+ Fatal | PhaseFatal | Error => "error",
Warning => "warning",
Note => "note",
Help => "help",
expander.cx.syntax_env.insert(name, extension);
}
+ let err_count = cx.parse_sess.span_diagnostic.err_count();
let mut ret = expander.fold_crate(c);
ret.exported_macros = expander.cx.exported_macros.clone();
- cx.parse_sess.span_diagnostic.abort_if_errors();
+
+ if cx.parse_sess.span_diagnostic.err_count() > err_count {
+ cx.parse_sess.span_diagnostic.abort_if_errors();
+ }
+
ret
};
return (ret, cx.syntax_env.names);
cfg,
name,
source);
- maybe_aborted(panictry!(p.parse_crate_mod()),p)
+ panictry!(p.parse_crate_mod())
}
pub fn parse_crate_attrs_from_source_str(name: String,
cfg,
name,
source);
- maybe_aborted(panictry!(p.parse_inner_attributes()), p)
+ panictry!(p.parse_inner_attributes())
}
pub fn parse_expr_from_source_str(name: String,
sess: &ParseSess)
-> P<ast::Expr> {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
- maybe_aborted(panictry!(p.parse_expr()), p)
+ panictry!(p.parse_expr())
}
pub fn parse_item_from_source_str(name: String,
sess: &ParseSess)
-> Option<P<ast::Item>> {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
- maybe_aborted(panictry!(p.parse_item()), p)
+ panictry!(p.parse_item())
}
pub fn parse_meta_from_source_str(name: String,
sess: &ParseSess)
-> P<ast::MetaItem> {
let mut p = new_parser_from_source_str(sess, cfg, name, source);
- maybe_aborted(panictry!(p.parse_meta_item()), p)
+ panictry!(p.parse_meta_item())
}
pub fn parse_stmt_from_source_str(name: String,
name,
source
);
- maybe_aborted(panictry!(p.parse_stmt()), p)
+ panictry!(p.parse_stmt())
}
// Warning: This parses with quote_depth > 0, which is not the default.
);
p.quote_depth += 1;
// right now this is re-creating the token trees from ... token trees.
- maybe_aborted(panictry!(p.parse_all_token_trees()),p)
+ panictry!(p.parse_all_token_trees())
}
// Create a new parser from a source string
p
}
-/// Abort if necessary
-pub fn maybe_aborted<T>(result: T, p: Parser) -> T {
- p.abort_if_errors();
- result
-}
fn abort_if_errors<'a, T>(result: PResult<'a, T>, p: &Parser) -> T {
match result {
Ok(c) => {
- p.abort_if_errors();
c
}
Err(mut e) => {
// Assuming we have just parsed `.foo` (i.e., a dot and an ident), continue
// parsing into an expression.
- fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, self_value: P<Expr>) -> PResult<'a, P<Expr>> {
+ fn parse_dot_suffix(&mut self,
+ ident: Ident,
+ ident_span: Span,
+ self_value: P<Expr>)
+ -> PResult<'a, P<Expr>> {
let (_, tys, bindings) = if self.eat(&token::ModSep) {
try!(self.expect_lt());
try!(self.parse_generic_values_after_lt())
}
_ => {
- // TODO special case lifetime
// FIXME Could factor this out into non_fatal_unexpected or something.
let actual = self.this_token_to_string();
self.span_err(self.span, &format!("unexpected token: `{}`", actual));