diff options
| author | bors <bors@rust-lang.org> | 2015-12-30 12:27:10 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-12-30 12:27:10 +0000 |
| commit | 176ee349a704a1aee9dfb79c27c5da20db7942a5 (patch) | |
| tree | 99e1ead256ccd196b4135455ef037b14ab3094fa /src/libsyntax | |
| parent | a06bb977d86dcfe786d4265f4807a11c39b51141 (diff) | |
| parent | 04d972906d05e6c27452e1ae35970c30e7cf6e6b (diff) | |
| download | rust-176ee349a704a1aee9dfb79c27c5da20db7942a5.tar.gz rust-176ee349a704a1aee9dfb79c27c5da20db7942a5.zip | |
Auto merge of #30542 - nrc:errs-base, r=nagisa
As discussed [here](https://internals.rust-lang.org/t/more-structured-errors/3005) r? @nikomatsakis or anyone else on the @rust-lang/compiler team
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/macros.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/plugin.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/errors/emitter.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/errors/mod.rs | 294 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 36 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/unicode_chars.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/parse/obsolete.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 468 | ||||
| -rw-r--r-- | src/libsyntax/show_span.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/util/parser_testing.rs | 20 |
21 files changed, 784 insertions, 400 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 26662605ba8..96d0052cf18 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -305,8 +305,10 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Inte if let s@Some(_) = attr.value_str() { s } else { - diag.span_err(attr.span, "export_name attribute has invalid format"); - diag.help("use #[export_name=\"*\"]"); + diag.struct_span_err(attr.span, + "export_name attribute has invalid format") + .help("use #[export_name=\"*\"]") + .emit(); None } } else { diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs index 3c8347f8a8e..95a74d87554 100644 --- a/src/libsyntax/diagnostics/macros.rs +++ b/src/libsyntax/diagnostics/macros.rs @@ -31,6 +31,14 @@ macro_rules! span_err { } #[macro_export] +macro_rules! span_warn { + ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ + __diagnostic_used!($code); + $session.span_warn_with_code($span, &format!($($message)*), stringify!($code)) + }) +} + +#[macro_export] macro_rules! span_err_or_warn { ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ __diagnostic_used!($code); @@ -43,31 +51,59 @@ macro_rules! span_err_or_warn { } #[macro_export] -macro_rules! span_warn { +macro_rules! struct_span_fatal { ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ __diagnostic_used!($code); - $session.span_warn_with_code($span, &format!($($message)*), stringify!($code)) + $session.struct_span_fatal_with_code($span, &format!($($message)*), stringify!($code)) + }) +} + +#[macro_export] +macro_rules! struct_span_err { + ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ + __diagnostic_used!($code); + $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code)) + }) +} + +#[macro_export] +macro_rules! struct_span_warn { + ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ + __diagnostic_used!($code); + $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code)) + }) +} + +#[macro_export] +macro_rules! struct_span_err_or_warn { + ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ + __diagnostic_used!($code); + if $is_warning { + $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code)) + } else { + $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code)) + } }) } #[macro_export] macro_rules! span_note { - ($session:expr, $span:expr, $($message:tt)*) => ({ - ($session).span_note($span, &format!($($message)*)) + ($err:expr, $span:expr, $($message:tt)*) => ({ + ($err).span_note($span, &format!($($message)*)); }) } #[macro_export] macro_rules! span_help { - ($session:expr, $span:expr, $($message:tt)*) => ({ - ($session).span_help($span, &format!($($message)*)) + ($err:expr, $span:expr, $($message:tt)*) => ({ + ($err).span_help($span, &format!($($message)*)); }) } #[macro_export] macro_rules! fileline_help { - ($session:expr, $span:expr, $($message:tt)*) => ({ - ($session).fileline_help($span, &format!($($message)*)) + ($err:expr, $span:expr, $($message:tt)*) => ({ + ($err).fileline_help($span, &format!($($message)*)); }) } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index be0d5729c70..d17ca3892dc 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -62,10 +62,10 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, match diagnostics.get_mut(&code.name) { // Previously used errors. Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => { - ecx.span_warn(span, &format!( + ecx.struct_span_warn(span, &format!( "diagnostic code {} already used", code - )); - ecx.span_note(previous_span, "previous invocation"); + )).span_note(previous_span, "previous invocation") + .emit(); } // Newly used errors. Some(ref mut info) => { diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index 7fef85a833e..a7bfdedf718 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -13,7 +13,7 @@ use self::Destination::*; use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span}; use diagnostics; -use errors::{Level, RenderSpan}; +use errors::{Level, RenderSpan, DiagnosticBuilder}; use errors::RenderSpan::*; use errors::Level::*; @@ -27,6 +27,17 @@ use term; pub trait Emitter { fn emit(&mut self, span: Option<Span>, msg: &str, code: Option<&str>, lvl: Level); fn custom_emit(&mut self, sp: RenderSpan, msg: &str, lvl: Level); + + /// Emit a structured diagnostic. + fn emit_struct(&mut self, db: &DiagnosticBuilder) { + self.emit(db.span, &db.message, db.code.as_ref().map(|s| &**s), db.level); + for child in &db.children { + match child.render_span { + Some(ref sp) => self.custom_emit(sp.clone(), &child.message, child.level), + None => self.emit(child.span, &child.message, None, child.level), + } + } + } } /// maximum number of lines we will print for each error; arbitrary. @@ -49,8 +60,8 @@ impl ColorConfig { } } -// A basic emitter for when we don't have access to a codemap or registry. Used -// for reporting very early errors, etc. +/// A basic emitter for when we don't have access to a codemap or registry. Used +/// for reporting very early errors, etc. pub struct BasicEmitter { dst: Destination, } @@ -111,9 +122,8 @@ impl Emitter for EmitterWriter { sp: RenderSpan, msg: &str, lvl: Level) { - match self.emit_(sp, msg, None, lvl) { - Ok(()) => {} - Err(e) => panic!("failed to print diagnostics: {:?}", e), + if let Err(e) = self.emit_(sp, msg, None, lvl) { + panic!("failed to print diagnostics: {:?}", e); } } } diff --git a/src/libsyntax/errors/mod.rs b/src/libsyntax/errors/mod.rs index f2e61090ba2..a2fae975148 100644 --- a/src/libsyntax/errors/mod.rs +++ b/src/libsyntax/errors/mod.rs @@ -98,6 +98,171 @@ impl error::Error for ExplicitBug { } } +/// Used for emitting structured error messages and other diagnostic information. +#[must_use] +pub struct DiagnosticBuilder<'a> { + emitter: &'a RefCell<Box<Emitter>>, + level: Level, + message: String, + code: Option<String>, + span: Option<Span>, + children: Vec<SubDiagnostic>, +} + +/// For example a note attached to an error. +struct SubDiagnostic { + level: Level, + message: String, + span: Option<Span>, + render_span: Option<RenderSpan>, +} + +impl<'a> DiagnosticBuilder<'a> { + /// Emit the diagnostic. + pub fn emit(&mut self) { + if self.cancelled() { + return; + } + + self.emitter.borrow_mut().emit_struct(&self); + self.cancel(); + + // if self.is_fatal() { + // panic!(FatalError); + // } + } + + /// Cancel the diagnostic (a structured diagnostic must either be emitted or + /// cancelled or it will panic when dropped). + /// BEWARE: if this DiagnosticBuilder is an error, then creating it will + /// bump the error count on the Handler and cancelling it won't undo that. + /// If you want to decrement the error count you should use `Handler::cancel`. + pub fn cancel(&mut self) { + self.level = Level::Cancelled; + } + + pub fn cancelled(&self) -> bool { + self.level == Level::Cancelled + } + + pub fn is_fatal(&self) -> bool { + self.level == Level::Fatal + } + + pub fn note(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Note, msg, None, None); + self + } + pub fn span_note(&mut self , + sp: Span, + msg: &str) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Note, msg, Some(sp), None); + self + } + pub fn help(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Help, msg, None, None); + self + } + pub fn span_help(&mut self , + sp: Span, + msg: &str) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Help, msg, Some(sp), None); + self + } + /// Prints out a message with a suggested edit of the code. + /// + /// See `diagnostic::RenderSpan::Suggestion` for more information. + pub fn span_suggestion(&mut self , + sp: Span, + msg: &str, + suggestion: String) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Help, msg, Some(sp), Some(Suggestion(sp, suggestion))); + self + } + pub fn span_end_note(&mut self , + sp: Span, + msg: &str) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Note, msg, Some(sp), Some(EndSpan(sp))); + self + } + pub fn fileline_note(&mut self , + sp: Span, + msg: &str) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Note, msg, Some(sp), Some(FileLine(sp))); + self + } + pub fn fileline_help(&mut self , + sp: Span, + msg: &str) + -> &mut DiagnosticBuilder<'a> { + self.sub(Level::Help, msg, Some(sp), Some(FileLine(sp))); + self + } + + pub fn span(&mut self, sp: Span) -> &mut Self { + self.span = Some(sp); + self + } + + pub fn code(&mut self, s: String) -> &mut Self { + self.code = Some(s); + self + } + + /// Convenience function for internal use, clients should use one of the + /// struct_* methods on Handler. + fn new(emitter: &'a RefCell<Box<Emitter>>, + level: Level, + message: &str) -> DiagnosticBuilder<'a> { + DiagnosticBuilder { + emitter: emitter, + level: level, + message: message.to_owned(), + code: None, + span: None, + children: vec![], + } + } + + /// Convenience function for internal use, clients should use one of the + /// public methods above. + fn sub(&mut self, + level: Level, + message: &str, + span: Option<Span>, + render_span: Option<RenderSpan>) { + let sub = SubDiagnostic { + level: level, + message: message.to_owned(), + span: span, + render_span: render_span, + }; + self.children.push(sub); + } +} + +impl<'a> fmt::Debug for DiagnosticBuilder<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.message.fmt(f) + } +} + +/// Destructor bomb - a DiagnosticBuilder must be either emitted or cancelled or +/// we emit a bug. +impl<'a> Drop for DiagnosticBuilder<'a> { + fn drop(&mut self) { + if !self.cancelled() { + self.emitter.borrow_mut().emit(None, "Error constructed but not emitted", None, Bug); + panic!(); + } + } +} + /// A handler deals with errors; certain errors /// (fatal, bug, unimpl) may cause immediate exit, /// others log errors for later reporting. @@ -132,11 +297,104 @@ impl Handler { } } + pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> { + DiagnosticBuilder::new(&self.emit, Level::Cancelled, "") + } + + pub fn struct_span_warn<'a>(&'a self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg); + result.span(sp); + if !self.can_emit_warnings { + result.cancel(); + } + result + } + pub fn struct_span_warn_with_code<'a>(&'a self, + sp: Span, + msg: &str, + code: &str) + -> DiagnosticBuilder<'a> { + let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg); + result.span(sp); + result.code(code.to_owned()); + if !self.can_emit_warnings { + result.cancel(); + } + result + } + pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg); + if !self.can_emit_warnings { + result.cancel(); + } + result + } + pub fn struct_span_err<'a>(&'a self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + self.bump_err_count(); + let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg); + result.span(sp); + result + } + pub fn struct_span_err_with_code<'a>(&'a self, + sp: Span, + msg: &str, + code: &str) + -> DiagnosticBuilder<'a> { + self.bump_err_count(); + let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg); + result.span(sp); + result.code(code.to_owned()); + result + } + pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + self.bump_err_count(); + DiagnosticBuilder::new(&self.emit, Level::Error, msg) + } + pub fn struct_span_fatal<'a>(&'a self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + self.bump_err_count(); + let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg); + result.span(sp); + result + } + pub fn struct_span_fatal_with_code<'a>(&'a self, + sp: Span, + msg: &str, + code: &str) + -> DiagnosticBuilder<'a> { + self.bump_err_count(); + let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg); + result.span(sp); + result.code(code.to_owned()); + result + } + pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> { + self.bump_err_count(); + DiagnosticBuilder::new(&self.emit, Level::Fatal, msg) + } + + pub fn cancel(&mut self, err: &mut DiagnosticBuilder) { + if err.level == Level::Error || err.level == Level::Fatal { + assert!(self.has_errors()); + self.err_count.set(self.err_count.get() + 1); + } + err.cancel(); + } + pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError { if self.treat_err_as_bug { self.span_bug(sp, msg); } self.emit(Some(sp), msg, Fatal); + self.bump_err_count(); return FatalError; } pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> FatalError { @@ -144,6 +402,7 @@ impl Handler { self.span_bug(sp, msg); } self.emit_with_code(Some(sp), msg, code, Fatal); + self.bump_err_count(); return FatalError; } pub fn span_err(&self, sp: Span, msg: &str) { @@ -166,27 +425,6 @@ impl Handler { pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) { self.emit_with_code(Some(sp), msg, code, Warning); } - pub fn span_note(&self, sp: Span, msg: &str) { - self.emit(Some(sp), msg, Note); - } - pub fn span_end_note(&self, sp: Span, msg: &str) { - self.custom_emit(EndSpan(sp), msg, Note); - } - pub fn span_help(&self, sp: Span, msg: &str) { - self.emit(Some(sp), msg, Help); - } - /// Prints out a message with a suggested edit of the code. - /// - /// See `diagnostic::RenderSpan::Suggestion` for more information. - pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) { - self.custom_emit(Suggestion(sp, suggestion), msg, Help); - } - pub fn fileline_note(&self, sp: Span, msg: &str) { - self.custom_emit(FileLine(sp), msg, Note); - } - pub fn fileline_help(&self, sp: Span, msg: &str) { - self.custom_emit(FileLine(sp), msg, Help); - } pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.emit(Some(sp), msg, Bug); panic!(ExplicitBug); @@ -199,6 +437,9 @@ impl Handler { self.emit(Some(sp), msg, Bug); self.bump_err_count(); } + pub fn span_note_without_error(&self, sp: Span, msg: &str) { + self.emit.borrow_mut().emit(Some(sp), msg, None, Note); + } pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { self.span_bug(sp, &format!("unimplemented {}", msg)); } @@ -207,6 +448,7 @@ impl Handler { self.bug(msg); } self.emit.borrow_mut().emit(None, msg, None, Fatal); + self.bump_err_count(); FatalError } pub fn err(&self, msg: &str) { @@ -219,12 +461,9 @@ impl Handler { pub fn warn(&self, msg: &str) { self.emit.borrow_mut().emit(None, msg, None, Warning); } - pub fn note(&self, msg: &str) { + pub fn note_without_error(&self, msg: &str) { self.emit.borrow_mut().emit(None, msg, None, Note); } - pub fn help(&self, msg: &str) { - self.emit.borrow_mut().emit(None, msg, None, Help); - } pub fn bug(&self, msg: &str) -> ! { self.emit.borrow_mut().emit(None, msg, None, Bug); panic!(ExplicitBug); @@ -266,7 +505,7 @@ impl Handler { } } - panic!(self.fatal(&s[..])); + panic!(self.fatal(&s)); } pub fn emit(&self, @@ -301,6 +540,7 @@ pub enum Level { Warning, Note, Help, + Cancelled, } impl fmt::Display for Level { @@ -313,6 +553,7 @@ impl fmt::Display for Level { Warning => "warning".fmt(f), Note => "note".fmt(f), Help => "help".fmt(f), + Cancelled => unreachable!(), } } } @@ -324,6 +565,7 @@ impl Level { Warning => term::color::BRIGHT_YELLOW, Note => term::color::BRIGHT_GREEN, Help => term::color::BRIGHT_CYAN, + Cancelled => unreachable!(), } } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f616420218e..fc0f1925207 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -14,6 +14,7 @@ use ast; use ast::Name; use codemap; use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION}; +use errors::DiagnosticBuilder; use ext; use ext::expand; use ext::tt::macro_rules; @@ -678,6 +679,25 @@ impl<'a> ExtCtxt<'a> { } } + pub fn struct_span_warn(&self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + self.parse_sess.span_diagnostic.struct_span_warn(sp, msg) + } + pub fn struct_span_err(&self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + self.parse_sess.span_diagnostic.struct_span_err(sp, msg) + } + pub fn struct_span_fatal(&self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg) + } + /// Emit `msg` attached to `sp`, and stop compilation immediately. /// /// `span_err` should be strongly preferred where-ever possible: @@ -710,15 +730,6 @@ impl<'a> ExtCtxt<'a> { pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } - pub fn span_note(&self, sp: Span, msg: &str) { - self.parse_sess.span_diagnostic.span_note(sp, msg); - } - pub fn span_help(&self, sp: Span, msg: &str) { - self.parse_sess.span_diagnostic.span_help(sp, msg); - } - pub fn fileline_help(&self, sp: Span, msg: &str) { - self.parse_sess.span_diagnostic.fileline_help(sp, msg); - } pub fn bug(&self, msg: &str) -> ! { self.parse_sess.span_diagnostic.bug(msg); } @@ -743,10 +754,13 @@ impl<'a> ExtCtxt<'a> { token::intern(st) } - pub fn suggest_macro_name(&mut self, name: &str, span: Span) { + pub fn suggest_macro_name(&mut self, + name: &str, + span: Span, + err: &mut DiagnosticBuilder<'a>) { let names = &self.syntax_env.names; if let Some(suggestion) = find_best_match_for_name(names.iter(), name, None) { - self.fileline_help(span, &format!("did you mean `{}!`?", suggestion)); + err.fileline_help(span, &format!("did you mean `{}!`?", suggestion)); } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 743bcda18de..5f27bdfc98a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -201,11 +201,12 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, let extname = pth.segments[0].identifier.name; match fld.cx.syntax_env.find(extname) { None => { - fld.cx.span_err( + let mut err = fld.cx.struct_span_err( pth.span, &format!("macro undefined: '{}!'", &extname)); - fld.cx.suggest_macro_name(&extname.as_str(), pth.span); + fld.cx.suggest_macro_name(&extname.as_str(), pth.span, &mut err); + err.emit(); // let compilation continue None @@ -334,11 +335,15 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool for attr in attrs { let mut is_use = attr.check_name("macro_use"); if attr.check_name("macro_escape") { - fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use"); + let mut err = + fld.cx.struct_span_warn(attr.span, + "macro_escape is a deprecated synonym for macro_use"); is_use = true; if let ast::AttrStyle::Inner = attr.node.style { - fld.cx.fileline_help(attr.span, "consider an outer attribute, \ - #[macro_use] mod ..."); + err.fileline_help(attr.span, "consider an outer attribute, \ + #[macro_use] mod ...").emit(); + } else { + err.emit(); } }; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 0c3a8b05fba..7a1a207a562 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -802,7 +802,7 @@ fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[TokenTree]) let cx_expr = panictry!(p.parse_expr()); if !panictry!(p.eat(&token::Comma)) { - panic!(p.fatal("expected token `,`")); + let _ = p.diagnostic().fatal("expected token `,`"); } let tts = panictry!(p.parse_all_token_trees()); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 7899e170ecf..f00224bacdd 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -117,11 +117,9 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree while self.p.token != token::Eof { match panictry!(self.p.parse_item()) { Some(item) => ret.push(item), - None => panic!(self.p.span_fatal( - self.p.span, - &format!("expected item, found `{}`", - self.p.this_token_to_string()) - )) + None => panic!(self.p.diagnostic().span_fatal(self.p.span, + &format!("expected item, found `{}`", + self.p.this_token_to_string()))) } } Some(ret) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index fb09118035c..166d32a8cc6 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -82,6 +82,7 @@ use ast; use ast::{TokenTree, Name, Ident}; use codemap::{BytePos, mk_sp, Span, Spanned}; use codemap; +use errors::FatalError; use parse::lexer::*; //resolve bug? use parse::ParseSess; use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; @@ -499,11 +500,12 @@ pub fn parse(sess: &ParseSess, } } -pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { +pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { match name { "tt" => { p.quote_depth += 1; //but in theory, non-quoted tts might be useful - let res = token::NtTT(P(panictry!(p.parse_token_tree()))); + let res: ::parse::PResult<'a, _> = p.parse_token_tree(); + let res = token::NtTT(P(panictry!(res))); p.quote_depth -= 1; return res; } @@ -514,12 +516,18 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { match name { "item" => match panictry!(p.parse_item()) { Some(i) => token::NtItem(i), - None => panic!(p.fatal("expected an item keyword")) + None => { + p.fatal("expected an item keyword").emit(); + panic!(FatalError); + } }, "block" => token::NtBlock(panictry!(p.parse_block())), "stmt" => match panictry!(p.parse_stmt()) { Some(s) => token::NtStmt(s), - None => panic!(p.fatal("expected a statement")) + None => { + p.fatal("expected a statement").emit(); + panic!(FatalError); + } }, "pat" => token::NtPat(panictry!(p.parse_pat())), "expr" => token::NtExpr(panictry!(p.parse_expr())), @@ -532,8 +540,9 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { } _ => { let token_str = pprust::token_to_string(&p.token); - panic!(p.fatal(&format!("expected ident, found {}", - &token_str[..]))) + p.fatal(&format!("expected ident, found {}", + &token_str[..])).emit(); + panic!(FatalError) } }, "path" => { @@ -541,11 +550,12 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal { }, "meta" => token::NtMeta(panictry!(p.parse_meta_item())), _ => { - panic!(p.span_fatal_help(sp, - &format!("invalid fragment specifier `{}`", name), - "valid fragment specifiers are `ident`, `block`, \ - `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ - and `item`")) + p.span_fatal_help(sp, + &format!("invalid fragment specifier `{}`", name), + "valid fragment specifiers are `ident`, `block`, \ + `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ + and `item`").emit(); + panic!(FatalError); } } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index fae60d28032..fd0bbf7a072 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -55,12 +55,12 @@ impl<'a> ParserAnyMacro<'a> { following", token_str); let span = parser.span; - parser.span_err(span, &msg[..]); - + let mut err = parser.diagnostic().struct_span_err(span, &msg[..]); let msg = format!("caused by the macro expansion here; the usage \ of `{}!` is likely invalid in {} context", self.macro_ident, context); - parser.span_note(self.site_span, &msg[..]); + err.span_note(self.site_span, &msg[..]) + .emit(); } } } @@ -111,7 +111,10 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(stmt) => ret.push(stmt), None => (), }, - Err(_) => break, + Err(mut e) => { + e.emit(); + break; + } } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 4ea0fd76fea..a23dc3b8871 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -725,17 +725,21 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs GateIssue::Library(lib) => lib, }; - if let Some(n) = issue { - diag.span_err(span, &format!("{} (see issue #{})", explain, n)); + let mut err = if let Some(n) = issue { + diag.struct_span_err(span, &format!("{} (see issue #{})", explain, n)) } else { - diag.span_err(span, explain); - } + diag.struct_span_err(span, explain) + }; // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; } - diag.fileline_help(span, &format!("add #![feature({})] to the \ - crate attributes to enable", - feature)); + if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { + err.emit(); + return; + } + err.fileline_help(span, &format!("add #![feature({})] to the \ + crate attributes to enable", + feature)); + err.emit(); } pub const EXPLAIN_ASM: &'static str = @@ -942,11 +946,13 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { self.gate_feature("braced_empty_structs", span, "empty structs and enum variants with braces are unstable"); } else if s.is_tuple() { - self.context.span_handler.span_err(span, "empty tuple structs and enum variants \ - are not allowed, use unit structs and \ - enum variants instead"); - self.context.span_handler.span_help(span, "remove trailing `()` to make a unit \ - struct or unit enum variant"); + self.context.span_handler.struct_span_err(span, "empty tuple structs and enum \ + variants are not allowed, use \ + unit structs and enum variants \ + instead") + .span_help(span, "remove trailing `()` to make a unit \ + struct or unit enum variant") + .emit(); } } visit::walk_struct_def(self, s) diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c09e35f1077..795f4044f6e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -40,17 +40,22 @@ extern crate libc; extern crate serialize as rustc_serialize; // used by deriving -// A variant of 'try!' that panics on Err(FatalError). This is used as a -// crutch on the way towards a non-panic!-prone parser. It should be used -// for fatal parsing errors; eventually we plan to convert all code using -// panictry to just use normal try +// A variant of 'try!' that panics on an Err. This is used as a crutch on the +// way towards a non-panic!-prone parser. It should be used for fatal parsing +// errors; eventually we plan to convert all code using panictry to just use +// normal try. +// Exported for syntax_ext, not meant for general use. +#[macro_export] macro_rules! panictry { ($e:expr) => ({ use std::result::Result::{Ok, Err}; - use errors::FatalError; + use $crate::errors::FatalError; match $e { Ok(e) => e, - Err(FatalError) => panic!(FatalError) + Err(mut e) => { + e.emit(); + panic!(FatalError); + } } }) } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 5df2478d487..35ec3dcb0fd 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -19,7 +19,7 @@ use ptr::P; impl<'a> Parser<'a> { /// Parse attributes that appear before an item - pub fn parse_outer_attributes(&mut self) -> PResult<Vec<ast::Attribute>> { + pub fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { let mut attrs: Vec<ast::Attribute> = Vec::new(); loop { debug!("parse_outer_attributes: self.token={:?}", @@ -51,7 +51,7 @@ impl<'a> Parser<'a> { /// /// If permit_inner is true, then a leading `!` indicates an inner /// attribute - pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute> { + pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> { debug!("parse_attributes: permit_inner={:?} self.token={:?}", permit_inner, self.token); let (span, value, mut style) = match self.token { @@ -64,11 +64,13 @@ impl<'a> Parser<'a> { try!(self.bump()); if !permit_inner { let span = self.span; - self.span_err(span, - "an inner attribute is not permitted in \ - this context"); - self.fileline_help(span, - "place inner attribute at the top of the module or block"); + self.diagnostic().struct_span_err(span, + "an inner attribute is not permitted in \ + this context") + .fileline_help(span, + "place inner attribute at the top of \ + the module or block") + .emit() } ast::AttrStyle::Inner } else { @@ -111,7 +113,7 @@ impl<'a> Parser<'a> { /// terminated by a semicolon. /// matches inner_attrs* - pub fn parse_inner_attributes(&mut self) -> PResult<Vec<ast::Attribute>> { + pub fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { let mut attrs: Vec<ast::Attribute> = vec![]; loop { match self.token { @@ -146,7 +148,7 @@ impl<'a> Parser<'a> { /// matches meta_item = IDENT /// | IDENT = lit /// | IDENT meta_seq - pub fn parse_meta_item(&mut self) -> PResult<P<ast::MetaItem>> { + pub fn parse_meta_item(&mut self) -> PResult<'a, P<ast::MetaItem>> { let nt_meta = match self.token { token::Interpolated(token::NtMeta(ref e)) => { Some(e.clone()) @@ -195,10 +197,10 @@ impl<'a> Parser<'a> { } /// matches meta_seq = ( COMMASEP(meta_item) ) - fn parse_meta_seq(&mut self) -> PResult<Vec<P<ast::MetaItem>>> { + fn parse_meta_seq(&mut self) -> PResult<'a, Vec<P<ast::MetaItem>>> { self.parse_unspanned_seq(&token::OpenDelim(token::Paren), &token::CloseDelim(token::Paren), seq_sep_trailing_allowed(token::Comma), - |p| p.parse_meta_item()) + |p: &mut Parser<'a>| p.parse_meta_item()) } } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 4619410ada7..3d8f3bcd526 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -11,7 +11,7 @@ use ast; use codemap::{BytePos, CharPos, CodeMap, Pos, Span}; use codemap; -use errors::{FatalError, Handler}; +use errors::{FatalError, Handler, DiagnosticBuilder}; use ext::tt::transcribe::tt_next_token; use parse::token::str_to_ident; use parse::token; @@ -173,10 +173,6 @@ impl<'a> StringReader<'a> { self.span_diagnostic.span_err(sp, m) } - /// Suggest some help with a given span. - pub fn help_span(&self, sp: Span, m: &str) { - self.span_diagnostic.span_help(sp, m) - } /// Report a fatal error spanning [`from_pos`, `to_pos`). fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> FatalError { @@ -188,11 +184,6 @@ impl<'a> StringReader<'a> { self.err_span(codemap::mk_sp(from_pos, to_pos), m) } - /// Suggest some help spanning [`from_pos`, `to_pos`). - fn help_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) { - self.help_span(codemap::mk_sp(from_pos, to_pos), m) - } - /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an /// escaped character to the error message fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError { @@ -201,6 +192,17 @@ impl<'a> StringReader<'a> { for c in c.escape_default() { m.push(c) } self.fatal_span_(from_pos, to_pos, &m[..]) } + fn struct_fatal_span_char(&self, + from_pos: BytePos, + to_pos: BytePos, + m: &str, + c: char) + -> DiagnosticBuilder<'a> { + let mut m = m.to_string(); + m.push_str(": "); + for c in c.escape_default() { m.push(c) } + self.span_diagnostic.struct_span_fatal(codemap::mk_sp(from_pos, to_pos), &m[..]) + } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an /// escaped character to the error message @@ -210,6 +212,17 @@ impl<'a> StringReader<'a> { for c in c.escape_default() { m.push(c) } self.err_span_(from_pos, to_pos, &m[..]); } + fn struct_err_span_char(&self, + from_pos: BytePos, + to_pos: BytePos, + m: &str, + c: char) + -> DiagnosticBuilder<'a> { + let mut m = m.to_string(); + m.push_str(": "); + for c in c.escape_default() { m.push(c) } + self.span_diagnostic.struct_span_err(codemap::mk_sp(from_pos, to_pos), &m[..]) + } /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the /// offending string to the error message @@ -746,10 +759,12 @@ impl<'a> StringReader<'a> { let valid = if self.curr_is('{') { self.scan_unicode_escape(delim) && !ascii_only } else { - self.err_span_(start, self.last_pos, - "incorrect unicode escape sequence"); - self.help_span_(start, self.last_pos, - "format of unicode escape sequences is `\\u{…}`"); + let span = codemap::mk_sp(start, self.last_pos); + self.span_diagnostic.struct_span_err(span, + "incorrect unicode escape sequence") + .span_help(span, + "format of unicode escape sequences is `\\u{…}`") + .emit(); false }; if ascii_only { @@ -771,21 +786,22 @@ impl<'a> StringReader<'a> { } c => { let last_pos = self.last_pos; - self.err_span_char( + let mut err = self.struct_err_span_char( escaped_pos, last_pos, if ascii_only { "unknown byte escape" } else { "unknown character escape" }, c); if e == '\r' { - self.help_span_(escaped_pos, last_pos, + err.span_help(codemap::mk_sp(escaped_pos, last_pos), "this is an isolated carriage return; consider checking \ - your editor and version control settings") + your editor and version control settings"); } if (e == '{' || e == '}') && !ascii_only { - self.help_span_(escaped_pos, last_pos, + err.span_help(codemap::mk_sp(escaped_pos, last_pos), "if used in a formatting string, \ - curly braces are escaped with `{{` and `}}`") + curly braces are escaped with `{{` and `}}`"); } + err.emit(); false } } @@ -1224,8 +1240,13 @@ impl<'a> StringReader<'a> { c => { let last_bpos = self.last_pos; let bpos = self.pos; - unicode_chars::check_for_substitution(&self, c); - panic!(self.fatal_span_char(last_bpos, bpos, "unknown start of token", c)) + let mut err = self.struct_fatal_span_char(last_bpos, + bpos, + "unknown start of token", + c); + unicode_chars::check_for_substitution(&self, c, &mut err); + err.emit(); + panic!(FatalError); } } } diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index a2f37426210..1d32dd49731 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -12,6 +12,7 @@ // http://www.unicode.org/Public/security/revision-06/confusables.txt use codemap::mk_sp as make_span; +use errors::DiagnosticBuilder; use super::StringReader; const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[ @@ -179,7 +180,9 @@ const ASCII_ARRAY: &'static [(char, &'static str)] = &[ ('=', "Equals Sign"), ('>', "Greater-Than Sign"), ]; -pub fn check_for_substitution(reader: &StringReader, ch: char) { +pub fn check_for_substitution<'a>(reader: &StringReader<'a>, + ch: char, + err: &mut DiagnosticBuilder<'a>) { UNICODE_ARRAY .iter() .find(|&&(c, _, _)| c == ch) @@ -190,7 +193,7 @@ pub fn check_for_substitution(reader: &StringReader, ch: char) { let msg = format!("unicode character '{}' ({}) looks much like '{}' ({}), but it's not", ch, u_name, ascii_char, ascii_name); - reader.help_span(span, &msg); + err.span_help(span, &msg); }, None => { reader diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 6951d6319ac..efbde0f85a6 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -12,7 +12,7 @@ use ast; use codemap::{self, Span, CodeMap, FileMap}; -use errors::{Handler, ColorConfig, FatalError}; +use errors::{Handler, ColorConfig, DiagnosticBuilder}; use parse::parser::Parser; use parse::token::InternedString; use ptr::P; @@ -25,7 +25,7 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::str; -pub type PResult<T> = Result<T, FatalError>; +pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>; #[macro_use] pub mod parser; @@ -76,8 +76,8 @@ pub fn parse_crate_from_file( cfg: ast::CrateConfig, sess: &ParseSess ) -> ast::Crate { - panictry!(new_parser_from_file(sess, cfg, input).parse_crate_mod()) - // why is there no p.abort_if_errors here? + let mut parser = new_parser_from_file(sess, cfg, input); + abort_if_errors(parser.parse_crate_mod(), &parser) } pub fn parse_crate_attrs_from_file( @@ -85,8 +85,8 @@ pub fn parse_crate_attrs_from_file( cfg: ast::CrateConfig, sess: &ParseSess ) -> Vec<ast::Attribute> { - // FIXME: maybe_aborted? - panictry!(new_parser_from_file(sess, cfg, input).parse_inner_attributes()) + let mut parser = new_parser_from_file(sess, cfg, input); + abort_if_errors(parser.parse_inner_attributes(), &parser) } pub fn parse_crate_from_source_str(name: String, @@ -271,6 +271,20 @@ pub fn maybe_aborted<T>(result: T, p: Parser) -> T { 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) => { + e.emit(); + p.abort_if_errors(); + unreachable!(); + } + } +} + /// Parse a string representing a character literal into its final form. /// Rather than just accepting/rejecting a given literal, unescapes it as /// well. Can take any slice prefixed by a character escape. Returns the @@ -449,11 +463,13 @@ fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>, Some(suf) => { if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) { // if it looks like a width, lets try to be helpful. - sd.span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..])); - sd.fileline_help(sp, "valid widths are 32 and 64"); + sd.struct_span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..])) + .fileline_help(sp, "valid widths are 32 and 64") + .emit(); } else { - sd.span_err(sp, &format!("invalid suffix `{}` for float literal", suf)); - sd.fileline_help(sp, "valid suffixes are `f32` and `f64`"); + sd.struct_span_err(sp, &format!("invalid suffix `{}` for float literal", suf)) + .fileline_help(sp, "valid suffixes are `f32` and `f64`") + .emit(); } ast::LitFloatUnsuffixed(data) @@ -622,13 +638,15 @@ pub fn integer_lit(s: &str, // i<digits> and u<digits> look like widths, so lets // give an error message along those lines if looks_like_width_suffix(&['i', 'u'], suf) { - sd.span_err(sp, &format!("invalid width `{}` for integer literal", - &suf[1..])); - sd.fileline_help(sp, "valid widths are 8, 16, 32 and 64"); + sd.struct_span_err(sp, &format!("invalid width `{}` for integer literal", + &suf[1..])) + .fileline_help(sp, "valid widths are 8, 16, 32 and 64") + .emit(); } else { - sd.span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf)); - sd.fileline_help(sp, "the suffix must be one of the integral types \ - (`u32`, `isize`, etc)"); + sd.struct_span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf)) + .fileline_help(sp, "the suffix must be one of the integral types \ + (`u32`, `isize`, etc)") + .emit(); } ty diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 5dba1e189ab..75f1ac49c9a 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -59,18 +59,17 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { kind_str: &str, desc: &str, error: bool) { - if error { - self.span_err(sp, &format!("obsolete syntax: {}", kind_str)); + let mut err = if error { + self.diagnostic().struct_span_err(sp, &format!("obsolete syntax: {}", kind_str)) } else { - self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)); - } + self.diagnostic().struct_span_warn(sp, &format!("obsolete syntax: {}", kind_str)) + }; if !self.obsolete_set.contains(&kind) && (error || self.sess.span_diagnostic.can_emit_warnings) { - self.sess - .span_diagnostic - .note(&format!("{}", desc)); + err.note(&format!("{}", desc)); self.obsolete_set.insert(kind); } + err.emit(); } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dbd34b49f7d..efd351a632d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -60,7 +60,7 @@ use attr::{ThinAttributes, ThinAttributesExt, AttributesExt}; use ast; use ast_util::{self, ident_to_path}; use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; -use errors::{self, FatalError}; +use errors::{self, DiagnosticBuilder}; use ext::tt::macro_parser; use parse; use parse::classify; @@ -392,14 +392,14 @@ impl<'a> Parser<'a> { Parser::token_to_string(&self.token) } - pub fn unexpected_last(&self, t: &token::Token) -> FatalError { + pub fn unexpected_last(&self, t: &token::Token) -> DiagnosticBuilder<'a> { let token_str = Parser::token_to_string(t); let last_span = self.last_span; self.span_fatal(last_span, &format!("unexpected token: `{}`", token_str)) } - pub fn unexpected(&mut self) -> FatalError { + pub fn unexpected(&mut self) -> DiagnosticBuilder<'a> { match self.expect_one_of(&[], &[]) { Err(e) => e, Ok(_) => unreachable!() @@ -408,7 +408,7 @@ impl<'a> Parser<'a> { /// Expect and consume the token t. Signal an error if /// the next token is not t. - pub fn expect(&mut self, t: &token::Token) -> PResult<()> { + pub fn expect(&mut self, t: &token::Token) -> PResult<'a, ()> { if self.expected_tokens.is_empty() { if self.token == *t { self.bump() @@ -429,7 +429,7 @@ impl<'a> Parser<'a> { /// anything. Signal a fatal error if next token is unexpected. pub fn expect_one_of(&mut self, edible: &[token::Token], - inedible: &[token::Token]) -> PResult<()>{ + inedible: &[token::Token]) -> PResult<'a, ()>{ fn tokens_to_string(tokens: &[TokenType]) -> String { let mut i = tokens.iter(); // This might be a sign we need a connect method on Iterator. @@ -484,7 +484,7 @@ impl<'a> Parser<'a> { /// true if and only if input was consumed for recovery. pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) - -> PResult<bool> { + -> PResult<'a, bool> { if self.token == token::OpenDelim(token::Brace) && expected.iter().all(|t| *t != token::OpenDelim(token::Brace)) && self.look_ahead(1, |t| *t == token::CloseDelim(token::Brace)) { @@ -504,7 +504,7 @@ impl<'a> Parser<'a> { /// followed by some token from the set edible + inedible. Recover /// from anticipated input errors, discarding erroneous characters. pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], - inedible: &[token::Token]) -> PResult<()> { + inedible: &[token::Token]) -> PResult<'a, ()> { debug!("commit_expr {:?}", e); if let ExprPath(..) = e.node { // might be unit-struct construction; check for recoverableinput error. @@ -517,7 +517,7 @@ impl<'a> Parser<'a> { self.expect_one_of(edible, inedible) } - pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResult<()> { + pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResult<'a, ()> { self.commit_expr(e, &[edible], &[]) } @@ -525,7 +525,7 @@ impl<'a> Parser<'a> { /// followed by some token from the set edible + inedible. Check /// for recoverable input errors, discarding erroneous characters. pub fn commit_stmt(&mut self, edible: &[token::Token], - inedible: &[token::Token]) -> PResult<()> { + inedible: &[token::Token]) -> PResult<'a, ()> { if self.last_token .as_ref() .map_or(false, |t| t.is_ident() || t.is_path()) { @@ -538,11 +538,11 @@ impl<'a> Parser<'a> { self.expect_one_of(edible, inedible) } - pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<()> { + pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<'a, ()> { self.commit_stmt(&[edible], &[]) } - pub fn parse_ident(&mut self) -> PResult<ast::Ident> { + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { self.check_strict_keywords(); try!(self.check_reserved_keywords()); match self.token { @@ -561,7 +561,7 @@ impl<'a> Parser<'a> { } } - pub fn parse_ident_or_self_type(&mut self) -> PResult<ast::Ident> { + pub fn parse_ident_or_self_type(&mut self) -> PResult<'a, ast::Ident> { if self.is_self_type_ident() { self.expect_self_type_ident() } else { @@ -569,7 +569,7 @@ impl<'a> Parser<'a> { } } - pub fn parse_path_list_item(&mut self) -> PResult<ast::PathListItem> { + pub fn parse_path_list_item(&mut self) -> PResult<'a, ast::PathListItem> { let lo = self.span.lo; let node = if try!(self.eat_keyword(keywords::SelfValue)) { let rename = try!(self.parse_rename()); @@ -595,7 +595,7 @@ impl<'a> Parser<'a> { /// Consume token 'tok' if it exists. Returns true if the given /// token was present, false otherwise. - pub fn eat(&mut self, tok: &token::Token) -> PResult<bool> { + pub fn eat(&mut self, tok: &token::Token) -> PResult<'a, bool> { let is_present = self.check(tok); if is_present { try!(self.bump())} Ok(is_present) @@ -608,7 +608,7 @@ impl<'a> Parser<'a> { /// If the next token is the given keyword, eat it and return /// true. Otherwise, return false. - pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<bool> { + pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> { if self.check_keyword(kw) { try!(self.bump()); Ok(true) @@ -617,7 +617,7 @@ impl<'a> Parser<'a> { } } - pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<bool> { + pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> { if self.token.is_keyword(kw) { try!(self.bump()); Ok(true) @@ -629,7 +629,7 @@ impl<'a> Parser<'a> { /// If the given word is not a keyword, signal an error. /// If the next token is not the given word, signal an error. /// Otherwise, eat it. - pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<()> { + pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> { if !try!(self.eat_keyword(kw) ){ self.expect_one_of(&[], &[]) } else { @@ -649,11 +649,10 @@ impl<'a> Parser<'a> { } /// Signal an error if the current token is a reserved keyword - pub fn check_reserved_keywords(&mut self) -> PResult<()>{ + pub fn check_reserved_keywords(&mut self) -> PResult<'a, ()>{ if self.token.is_reserved_keyword() { let token_str = self.this_token_to_string(); - Err(self.fatal(&format!("`{}` is a reserved keyword", - token_str))) + Err(self.fatal(&format!("`{}` is a reserved keyword", token_str))) } else { Ok(()) } @@ -661,7 +660,7 @@ impl<'a> Parser<'a> { /// Expect and consume an `&`. If `&&` is seen, replace it with a single /// `&` and continue. If an `&` is not seen, signal an error. - fn expect_and(&mut self) -> PResult<()> { + fn expect_and(&mut self) -> PResult<'a, ()> { self.expected_tokens.push(TokenType::Token(token::BinOp(token::And))); match self.token { token::BinOp(token::And) => self.bump(), @@ -693,7 +692,7 @@ impl<'a> Parser<'a> { /// /// This is meant to be used when parsing generics on a path to get the /// starting token. - fn eat_lt(&mut self) -> PResult<bool> { + fn eat_lt(&mut self) -> PResult<'a, bool> { self.expected_tokens.push(TokenType::Token(token::Lt)); match self.token { token::Lt => { try!(self.bump()); Ok(true)} @@ -707,7 +706,7 @@ impl<'a> Parser<'a> { } } - fn expect_lt(&mut self) -> PResult<()> { + fn expect_lt(&mut self) -> PResult<'a, ()> { if !try!(self.eat_lt()) { self.expect_one_of(&[], &[]) } else { @@ -718,7 +717,7 @@ impl<'a> Parser<'a> { /// Expect and consume a GT. if a >> is seen, replace it /// with a single > and continue. If a GT is not seen, /// signal an error. - pub fn expect_gt(&mut self) -> PResult<()> { + pub fn expect_gt(&mut self) -> PResult<'a, ()> { self.expected_tokens.push(TokenType::Token(token::Gt)); match self.token { token::Gt => self.bump(), @@ -750,8 +749,8 @@ impl<'a> Parser<'a> { pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self, sep: Option<token::Token>, mut f: F) - -> PResult<(P<[T]>, bool)> where - F: FnMut(&mut Parser) -> PResult<Option<T>>, + -> PResult<'a, (P<[T]>, bool)> + where F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>, { let mut v = Vec::new(); // This loop works by alternating back and forth between parsing types @@ -788,8 +787,8 @@ impl<'a> Parser<'a> { pub fn parse_seq_to_before_gt<T, F>(&mut self, sep: Option<token::Token>, mut f: F) - -> PResult<P<[T]>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, P<[T]>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let (result, returned) = try!(self.parse_seq_to_before_gt_or_return(sep, |p| Ok(Some(try!(f(p)))))); @@ -800,8 +799,8 @@ impl<'a> Parser<'a> { pub fn parse_seq_to_gt<T, F>(&mut self, sep: Option<token::Token>, f: F) - -> PResult<P<[T]>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, P<[T]>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let v = try!(self.parse_seq_to_before_gt(sep, f)); try!(self.expect_gt()); @@ -811,8 +810,8 @@ impl<'a> Parser<'a> { pub fn parse_seq_to_gt_or_return<T, F>(&mut self, sep: Option<token::Token>, f: F) - -> PResult<(P<[T]>, bool)> where - F: FnMut(&mut Parser) -> PResult<Option<T>>, + -> PResult<'a, (P<[T]>, bool)> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>, { let (v, returned) = try!(self.parse_seq_to_before_gt_or_return(sep, f)); if !returned { @@ -828,8 +827,8 @@ impl<'a> Parser<'a> { ket: &token::Token, sep: SeqSep, f: F) - -> PResult<Vec<T>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, Vec<T>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let val = try!(self.parse_seq_to_before_end(ket, sep, f)); try!(self.bump()); @@ -843,8 +842,8 @@ impl<'a> Parser<'a> { ket: &token::Token, sep: SeqSep, mut f: F) - -> PResult<Vec<T>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, Vec<T>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let mut first: bool = true; let mut v = vec!(); @@ -870,8 +869,8 @@ impl<'a> Parser<'a> { ket: &token::Token, sep: SeqSep, f: F) - -> PResult<Vec<T>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, Vec<T>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { try!(self.expect(bra)); let result = try!(self.parse_seq_to_before_end(ket, sep, f)); @@ -886,8 +885,8 @@ impl<'a> Parser<'a> { ket: &token::Token, sep: SeqSep, f: F) - -> PResult<Vec<T>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, Vec<T>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let result = try!(self.parse_unspanned_seq(bra, ket, sep, f)); if result.is_empty() { @@ -905,8 +904,8 @@ impl<'a> Parser<'a> { ket: &token::Token, sep: SeqSep, f: F) - -> PResult<Spanned<Vec<T>>> where - F: FnMut(&mut Parser) -> PResult<T>, + -> PResult<'a, Spanned<Vec<T>>> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let lo = self.span.lo; try!(self.expect(bra)); @@ -917,7 +916,7 @@ impl<'a> Parser<'a> { } /// Advance the parser by one token - pub fn bump(&mut self) -> PResult<()> { + pub fn bump(&mut self) -> PResult<'a, ()> { self.last_span = self.span; // Stash token for error recovery (sometimes; clone is not necessarily cheap). self.last_token = if self.token.is_ident() || @@ -950,7 +949,7 @@ impl<'a> Parser<'a> { } /// Advance the parser by one token and return the bumped token. - pub fn bump_and_get(&mut self) -> PResult<token::Token> { + pub fn bump_and_get(&mut self) -> PResult<'a, token::Token> { let old_token = mem::replace(&mut self.token, token::Underscore); try!(self.bump()); Ok(old_token) @@ -981,28 +980,16 @@ impl<'a> Parser<'a> { } f(&self.buffer[((self.buffer_start + dist - 1) & 3) as usize].tok) } - pub fn fatal(&self, m: &str) -> errors::FatalError { - self.sess.span_diagnostic.span_fatal(self.span, m) + pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> { + self.sess.span_diagnostic.struct_span_fatal(self.span, m) } - pub fn span_fatal(&self, sp: Span, m: &str) -> errors::FatalError { - self.sess.span_diagnostic.span_fatal(sp, m) + pub fn span_fatal(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> { + self.sess.span_diagnostic.struct_span_fatal(sp, m) } - pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> errors::FatalError { - self.span_err(sp, m); - self.fileline_help(sp, help); - errors::FatalError - } - pub fn span_note(&self, sp: Span, m: &str) { - self.sess.span_diagnostic.span_note(sp, m) - } - pub fn span_help(&self, sp: Span, m: &str) { - self.sess.span_diagnostic.span_help(sp, m) - } - pub fn span_suggestion(&self, sp: Span, m: &str, n: String) { - self.sess.span_diagnostic.span_suggestion(sp, m, n) - } - pub fn fileline_help(&self, sp: Span, m: &str) { - self.sess.span_diagnostic.fileline_help(sp, m) + pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> { + let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m); + err.fileline_help(sp, help); + err } pub fn bug(&self, m: &str) -> ! { self.sess.span_diagnostic.span_bug(self.span, m) @@ -1023,6 +1010,10 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.abort_if_errors(); } + pub fn diagnostic(&self) -> &'a errors::Handler { + &self.sess.span_diagnostic + } + pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString { id.name.as_str() } @@ -1042,7 +1033,7 @@ impl<'a> Parser<'a> { } } - pub fn parse_for_in_type(&mut self) -> PResult<Ty_> { + pub fn parse_for_in_type(&mut self) -> PResult<'a, Ty_> { /* Parses whatever can come after a `for` keyword in a type. The `for` has already been consumed. @@ -1085,12 +1076,12 @@ impl<'a> Parser<'a> { } } - pub fn parse_ty_path(&mut self) -> PResult<Ty_> { + pub fn parse_ty_path(&mut self) -> PResult<'a, Ty_> { Ok(TyPath(None, try!(self.parse_path(LifetimeAndTypesWithoutColons)))) } /// parse a TyBareFn type: - pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> PResult<Ty_> { + pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> PResult<'a, Ty_> { /* [unsafe] [extern "ABI"] fn <'lt> (S) -> T @@ -1127,7 +1118,7 @@ impl<'a> Parser<'a> { } /// Parses an obsolete closure kind (`&:`, `&mut:`, or `:`). - pub fn parse_obsolete_closure_kind(&mut self) -> PResult<()> { + pub fn parse_obsolete_closure_kind(&mut self) -> PResult<'a, ()> { let lo = self.span.lo; if self.check(&token::BinOp(token::And)) && @@ -1156,7 +1147,7 @@ impl<'a> Parser<'a> { Ok(()) } - pub fn parse_unsafety(&mut self) -> PResult<Unsafety> { + pub fn parse_unsafety(&mut self) -> PResult<'a, Unsafety> { if try!(self.eat_keyword(keywords::Unsafe)) { return Ok(Unsafety::Unsafe); } else { @@ -1165,12 +1156,12 @@ impl<'a> Parser<'a> { } /// Parse the items in a trait declaration - pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> { + pub fn parse_trait_items(&mut self) -> PResult<'a, Vec<P<TraitItem>>> { self.parse_unspanned_seq( &token::OpenDelim(token::Brace), &token::CloseDelim(token::Brace), seq_sep_none(), - |p| -> PResult<P<TraitItem>> { + |p| -> PResult<'a, P<TraitItem>> { maybe_whole!(no_clone p, NtTraitItem); let mut attrs = try!(p.parse_outer_attributes()); let lo = p.span.lo; @@ -1200,7 +1191,7 @@ impl<'a> Parser<'a> { let ident = try!(p.parse_ident()); let mut generics = try!(p.parse_generics()); - let (explicit_self, d) = try!(p.parse_fn_decl_with_self(|p|{ + let (explicit_self, d) = try!(p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{ // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a // definition... @@ -1251,14 +1242,14 @@ impl<'a> Parser<'a> { } /// Parse a possibly mutable type - pub fn parse_mt(&mut self) -> PResult<MutTy> { + pub fn parse_mt(&mut self) -> PResult<'a, MutTy> { let mutbl = try!(self.parse_mutability()); let t = try!(self.parse_ty()); Ok(MutTy { ty: t, mutbl: mutbl }) } /// Parse optional return type [ -> TY ] in function decl - pub fn parse_ret_ty(&mut self) -> PResult<FunctionRetTy> { + pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> { if try!(self.eat(&token::RArrow) ){ if try!(self.eat(&token::Not) ){ Ok(NoReturn(self.last_span)) @@ -1272,7 +1263,7 @@ impl<'a> Parser<'a> { } /// Parse a type in a context where `T1+T2` is allowed. - pub fn parse_ty_sum(&mut self) -> PResult<P<Ty>> { + pub fn parse_ty_sum(&mut self) -> PResult<'a, P<Ty>> { let lo = self.span.lo; let lhs = try!(self.parse_ty()); @@ -1297,7 +1288,7 @@ impl<'a> Parser<'a> { } /// Parse a type. - pub fn parse_ty(&mut self) -> PResult<P<Ty>> { + pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> { maybe_whole!(no_clone self, NtTy); let lo = self.span.lo; @@ -1397,7 +1388,7 @@ impl<'a> Parser<'a> { Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})) } - pub fn parse_borrowed_pointee(&mut self) -> PResult<Ty_> { + pub fn parse_borrowed_pointee(&mut self) -> PResult<'a, Ty_> { // look for `&'lt` or `&'foo ` and interpret `foo` as the region name: let opt_lifetime = try!(self.parse_opt_lifetime()); @@ -1405,7 +1396,7 @@ impl<'a> Parser<'a> { return Ok(TyRptr(opt_lifetime, mt)); } - pub fn parse_ptr(&mut self) -> PResult<MutTy> { + pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> { let mutbl = if try!(self.eat_keyword(keywords::Mut) ){ MutMutable } else if try!(self.eat_keyword(keywords::Const) ){ @@ -1443,7 +1434,7 @@ impl<'a> Parser<'a> { /// This version of parse arg doesn't necessarily require /// identifier names. - pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<Arg> { + pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { maybe_whole!(no_clone self, NtArg); let pat = if require_name || self.is_named_argument() { @@ -1470,12 +1461,12 @@ impl<'a> Parser<'a> { } /// Parse a single function argument - pub fn parse_arg(&mut self) -> PResult<Arg> { + pub fn parse_arg(&mut self) -> PResult<'a, Arg> { self.parse_arg_general(true) } /// Parse an argument in a lambda header e.g. |arg, arg| - pub fn parse_fn_block_arg(&mut self) -> PResult<Arg> { + pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> { let pat = try!(self.parse_pat()); let t = if try!(self.eat(&token::Colon) ){ try!(self.parse_ty_sum()) @@ -1493,7 +1484,7 @@ impl<'a> Parser<'a> { }) } - pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<Option<P<ast::Expr>>> { + pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> { if self.check(&token::Semi) { try!(self.bump()); Ok(Some(try!(self.parse_expr()))) @@ -1503,7 +1494,7 @@ impl<'a> Parser<'a> { } /// Matches token_lit = LIT_INTEGER | ... - pub fn lit_from_token(&self, tok: &token::Token) -> PResult<Lit_> { + pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, Lit_> { match *tok { token::Interpolated(token::NtExpr(ref v)) => { match v.node { @@ -1562,7 +1553,7 @@ impl<'a> Parser<'a> { } /// Matches lit = true | false | token_lit - pub fn parse_lit(&mut self) -> PResult<Lit> { + pub fn parse_lit(&mut self) -> PResult<'a, Lit> { let lo = self.span.lo; let lit = if try!(self.eat_keyword(keywords::True) ){ LitBool(true) @@ -1577,7 +1568,7 @@ impl<'a> Parser<'a> { } /// matches '-' lit | lit - pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<P<Expr>> { + pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> { let minus_lo = self.span.lo; let minus_present = try!(self.eat(&token::BinOp(token::Minus))); let lo = self.span.lo; @@ -1610,7 +1601,7 @@ impl<'a> Parser<'a> { /// `<T as U>::a` /// `<T as U>::F::a::<S>` pub fn parse_qualified_path(&mut self, mode: PathParsingMode) - -> PResult<(QSelf, ast::Path)> { + -> PResult<'a, (QSelf, ast::Path)> { let span = self.last_span; let self_type = try!(self.parse_ty_sum()); let mut path = if try!(self.eat_keyword(keywords::As)) { @@ -1653,7 +1644,7 @@ impl<'a> Parser<'a> { /// mode. The `mode` parameter determines whether lifetimes, types, and/or /// bounds are permitted and whether `::` must precede type parameter /// groups. - pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<ast::Path> { + pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<'a, ast::Path> { // Check for a whole path... let found = match self.token { token::Interpolated(token::NtPath(_)) => Some(try!(self.bump_and_get())), @@ -1696,7 +1687,7 @@ impl<'a> Parser<'a> { /// - `a::b<T,U>::c<V,W>` /// - `a::b<T,U>::c(V) -> W` /// - `a::b<T,U>::c(V)` - pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSegment>> { + pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> { let mut segments = Vec::new(); loop { // First, parse an identifier. @@ -1749,7 +1740,7 @@ impl<'a> Parser<'a> { /// Examples: /// - `a::b::<T,U>::c` - pub fn parse_path_segments_with_colons(&mut self) -> PResult<Vec<ast::PathSegment>> { + pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> { let mut segments = Vec::new(); loop { // First, parse an identifier. @@ -1794,7 +1785,7 @@ impl<'a> Parser<'a> { /// Examples: /// - `a::b::c` - pub fn parse_path_segments_without_types(&mut self) -> PResult<Vec<ast::PathSegment>> { + pub fn parse_path_segments_without_types(&mut self) -> PResult<'a, Vec<ast::PathSegment>> { let mut segments = Vec::new(); loop { // First, parse an identifier. @@ -1814,7 +1805,7 @@ impl<'a> Parser<'a> { } /// parses 0 or 1 lifetime - pub fn parse_opt_lifetime(&mut self) -> PResult<Option<ast::Lifetime>> { + pub fn parse_opt_lifetime(&mut self) -> PResult<'a, Option<ast::Lifetime>> { match self.token { token::Lifetime(..) => { Ok(Some(try!(self.parse_lifetime()))) @@ -1827,7 +1818,7 @@ impl<'a> Parser<'a> { /// Parses a single lifetime /// Matches lifetime = LIFETIME - pub fn parse_lifetime(&mut self) -> PResult<ast::Lifetime> { + pub fn parse_lifetime(&mut self) -> PResult<'a, ast::Lifetime> { match self.token { token::Lifetime(i) => { let span = self.span; @@ -1846,7 +1837,7 @@ impl<'a> Parser<'a> { /// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def = /// lifetime [':' lifetimes]` - pub fn parse_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> { + pub fn parse_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> { let mut res = Vec::new(); loop { @@ -1889,7 +1880,7 @@ impl<'a> Parser<'a> { /// Parses zero or more comma separated lifetimes. Expects each lifetime to be followed by /// either a comma or `>`. Used when parsing type parameter lists, where we expect something /// like `<'a, 'b, T>`. - pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<Vec<ast::Lifetime>> { + pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<'a, Vec<ast::Lifetime>> { let mut res = Vec::new(); loop { @@ -1911,7 +1902,7 @@ impl<'a> Parser<'a> { } /// Parse mutability declaration (mut/const/imm) - pub fn parse_mutability(&mut self) -> PResult<Mutability> { + pub fn parse_mutability(&mut self) -> PResult<'a, Mutability> { if try!(self.eat_keyword(keywords::Mut) ){ Ok(MutMutable) } else { @@ -1920,7 +1911,7 @@ impl<'a> Parser<'a> { } /// Parse ident COLON expr - pub fn parse_field(&mut self) -> PResult<Field> { + pub fn parse_field(&mut self) -> PResult<'a, Field> { let lo = self.span.lo; let i = try!(self.parse_ident()); let hi = self.last_span.hi; @@ -2012,7 +2003,7 @@ impl<'a> Parser<'a> { }) } - fn expect_open_delim(&mut self) -> PResult<token::DelimToken> { + fn expect_open_delim(&mut self) -> PResult<'a, token::DelimToken> { self.expected_tokens.push(TokenType::Token(token::Gt)); match self.token { token::OpenDelim(delim) => { @@ -2030,7 +2021,7 @@ impl<'a> Parser<'a> { /// NB: This does not parse outer attributes, /// and is private because it only works /// correctly if called from parse_dot_or_call_expr(). - fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> { + fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> { maybe_whole_expr!(self); // Outer attributes are already parsed and will be @@ -2294,7 +2285,7 @@ impl<'a> Parser<'a> { fn parse_or_use_outer_attributes(&mut self, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<ThinAttributes> { + -> PResult<'a, ThinAttributes> { if let Some(attrs) = already_parsed_attrs { Ok(attrs) } else { @@ -2305,7 +2296,7 @@ impl<'a> Parser<'a> { /// Parse a block or unsafe block pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode, attrs: ThinAttributes) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { let outer_attrs = attrs; try!(self.expect(&token::OpenDelim(token::Brace))); @@ -2320,7 +2311,7 @@ impl<'a> Parser<'a> { /// parse a.b or a(13) or a[4] or just a pub fn parse_dot_or_call_expr(&mut self, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); let b = try!(self.parse_bottom_expr()); @@ -2330,7 +2321,7 @@ impl<'a> Parser<'a> { pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>, attrs: ThinAttributes) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure @@ -2356,7 +2347,7 @@ impl<'a> Parser<'a> { ) } - fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<P<Expr>> { + fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<'a, P<Expr>> { let mut e = e0; let lo = e.span.lo; let mut hi; @@ -2437,18 +2428,19 @@ impl<'a> Parser<'a> { try!(self.bump()); let last_span = self.last_span; let fstr = n.as_str(); - self.span_err(last_span, - &format!("unexpected token: `{}`", n.as_str())); + let mut err = self.diagnostic().struct_span_err(last_span, + &format!("unexpected token: `{}`", n.as_str())); if fstr.chars().all(|x| "0123456789.".contains(x)) { let float = match fstr.parse::<f64>().ok() { Some(f) => f, None => continue, }; - self.fileline_help(last_span, + err.fileline_help(last_span, &format!("try parenthesizing the first index; e.g., `(foo.{}){}`", float.trunc() as usize, format!(".{}", fstr.splitn(2, ".").last().unwrap()))); } + err.emit(); self.abort_if_errors(); } @@ -2489,7 +2481,7 @@ impl<'a> Parser<'a> { } // Parse unquoted tokens after a `$` in a token tree - fn parse_unquoted(&mut self) -> PResult<TokenTree> { + fn parse_unquoted(&mut self) -> PResult<'a, TokenTree> { let mut sp = self.span; let (name, namep) = match self.token { token::Dollar => { @@ -2541,7 +2533,7 @@ impl<'a> Parser<'a> { } } - pub fn check_unknown_macro_variable(&mut self) -> PResult<()> { + pub fn check_unknown_macro_variable(&mut self) -> PResult<'a, ()> { if self.quote_depth == 0 { match self.token { token::SubstNt(name, _) => @@ -2555,8 +2547,9 @@ impl<'a> Parser<'a> { /// Parse an optional separator followed by a Kleene-style /// repetition token (+ or *). - pub fn parse_sep_and_kleene_op(&mut self) -> PResult<(Option<token::Token>, ast::KleeneOp)> { - fn parse_kleene_op(parser: &mut Parser) -> PResult<Option<ast::KleeneOp>> { + pub fn parse_sep_and_kleene_op(&mut self) + -> PResult<'a, (Option<token::Token>, ast::KleeneOp)> { + fn parse_kleene_op<'a>(parser: &mut Parser<'a>) -> PResult<'a, Option<ast::KleeneOp>> { match parser.token { token::BinOp(token::Star) => { try!(parser.bump()); @@ -2583,7 +2576,7 @@ impl<'a> Parser<'a> { } /// parse a single token tree from the input. - pub fn parse_token_tree(&mut self) -> PResult<TokenTree> { + pub fn parse_token_tree(&mut self) -> PResult<'a, TokenTree> { // FIXME #6994: currently, this is too eager. It // parses token trees but also identifies TokenType::Sequence's // and token::SubstNt's; it's too early to know yet @@ -2596,20 +2589,20 @@ impl<'a> Parser<'a> { // not an EOF, and not the desired right-delimiter (if // it were, parse_seq_to_before_end would have prevented // reaching this point. - fn parse_non_delim_tt_tok(p: &mut Parser) -> PResult<TokenTree> { + fn parse_non_delim_tt_tok<'b>(p: &mut Parser<'b>) -> PResult<'b, TokenTree> { maybe_whole!(deref p, NtTT); match p.token { token::CloseDelim(_) => { + let token_str = p.this_token_to_string(); + let mut err = p.fatal( + &format!("incorrect close delimiter: `{}`", token_str)); // This is a conservative error: only report the last unclosed delimiter. The // previous unclosed delimiters could actually be closed! The parser just hasn't // gotten to them yet. - match p.open_braces.last() { - None => {} - Some(&sp) => p.span_note(sp, "unclosed delimiter"), + if let Some(&sp) = p.open_braces.last() { + err.span_note(sp, "unclosed delimiter"); }; - let token_str = p.this_token_to_string(); - Err(p.fatal(&format!("incorrect close delimiter: `{}`", - token_str))) + Err(err) }, /* we ought to allow different depths of unquotation */ token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => { @@ -2624,12 +2617,12 @@ impl<'a> Parser<'a> { match self.token { token::Eof => { let open_braces = self.open_braces.clone(); + let mut err: DiagnosticBuilder<'a> = + self.fatal("this file contains an un-closed delimiter"); for sp in &open_braces { - self.span_help(*sp, "did you mean to close this delimiter?"); + err.span_help(*sp, "did you mean to close this delimiter?"); } - // There shouldn't really be a span, but it's easier for the test runner - // if we give it one - return Err(self.fatal("this file contains an un-closed delimiter ")); + return Err(err); }, token::OpenDelim(delim) => { // The span for beginning of the delimited section @@ -2668,7 +2661,7 @@ impl<'a> Parser<'a> { // parse a stream of tokens into a list of TokenTree's, // up to EOF. - pub fn parse_all_token_trees(&mut self) -> PResult<Vec<TokenTree>> { + pub fn parse_all_token_trees(&mut self) -> PResult<'a, Vec<TokenTree>> { let mut tts = Vec::new(); while self.token != token::Eof { tts.push(try!(self.parse_token_tree())); @@ -2679,7 +2672,7 @@ impl<'a> Parser<'a> { /// Parse a prefix-unary-operator expr pub fn parse_prefix_expr(&mut self, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); let lo = self.span.lo; let hi; @@ -2740,7 +2733,7 @@ impl<'a> Parser<'a> { /// the expression. pub fn parse_assoc_expr(&mut self, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { self.parse_assoc_expr_with(0, already_parsed_attrs.into()) } @@ -2748,7 +2741,7 @@ impl<'a> Parser<'a> { pub fn parse_assoc_expr_with(&mut self, min_prec: usize, lhs: LhsExpr) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs { expr } else { @@ -2879,12 +2872,13 @@ impl<'a> Parser<'a> { ExprBinary(op, _, _) if op.node.is_comparison() => { // respan to include both operators let op_span = mk_sp(op.span.lo, self.span.hi); - self.span_err(op_span, + let mut err = self.diagnostic().struct_span_err(op_span, "chained comparison operators require parentheses"); if op.node == BiLt && *outer_op == AssocOp::Greater { - self.fileline_help(op_span, + err.fileline_help(op_span, "use `::<...>` instead of `<...>` if you meant to specify type arguments"); } + err.emit(); } _ => {} } @@ -2893,7 +2887,7 @@ impl<'a> Parser<'a> { /// Parse prefix-forms of range notation: `..expr` and `..` fn parse_prefix_range_expr(&mut self, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { debug_assert!(self.token == token::DotDot); let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs)); let lo = self.span.lo; @@ -2928,7 +2922,7 @@ impl<'a> Parser<'a> { } /// Parse an 'if' or 'if let' expression ('if' token already eaten) - pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> { + pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { if self.check_keyword(keywords::Let) { return self.parse_if_let_expr(attrs); } @@ -2947,7 +2941,7 @@ impl<'a> Parser<'a> { /// Parse an 'if let' expression ('if' token already eaten) pub fn parse_if_let_expr(&mut self, attrs: ThinAttributes) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { let lo = self.last_span.lo; try!(self.expect_keyword(keywords::Let)); let pat = try!(self.parse_pat()); @@ -2967,7 +2961,7 @@ impl<'a> Parser<'a> { pub fn parse_lambda_expr(&mut self, lo: BytePos, capture_clause: CaptureClause, attrs: ThinAttributes) - -> PResult<P<Expr>> + -> PResult<'a, P<Expr>> { let decl = try!(self.parse_fn_block_decl()); let body = match decl.output { @@ -2997,7 +2991,7 @@ impl<'a> Parser<'a> { } // `else` token already eaten - pub fn parse_else_expr(&mut self) -> PResult<P<Expr>> { + pub fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> { if try!(self.eat_keyword(keywords::If) ){ return self.parse_if_expr(None); } else { @@ -3009,7 +3003,7 @@ impl<'a> Parser<'a> { /// Parse a 'for' .. 'in' expression ('for' token already eaten) pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos, - attrs: ThinAttributes) -> PResult<P<Expr>> { + attrs: ThinAttributes) -> PResult<'a, P<Expr>> { // Parse: `for <src_pat> in <src_expr> <src_loop_block>` let pat = try!(self.parse_pat()); @@ -3028,7 +3022,7 @@ impl<'a> Parser<'a> { /// Parse a 'while' or 'while let' expression ('while' token already eaten) pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos, - attrs: ThinAttributes) -> PResult<P<Expr>> { + attrs: ThinAttributes) -> PResult<'a, P<Expr>> { if self.token.is_keyword(keywords::Let) { return self.parse_while_let_expr(opt_ident, span_lo, attrs); } @@ -3043,7 +3037,7 @@ impl<'a> Parser<'a> { /// Parse a 'while let' expression ('while' token already eaten) pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos, - attrs: ThinAttributes) -> PResult<P<Expr>> { + attrs: ThinAttributes) -> PResult<'a, P<Expr>> { try!(self.expect_keyword(keywords::Let)); let pat = try!(self.parse_pat()); try!(self.expect(&token::Eq)); @@ -3057,7 +3051,7 @@ impl<'a> Parser<'a> { // parse `loop {...}`, `loop` token already eaten pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>, span_lo: BytePos, - attrs: ThinAttributes) -> PResult<P<Expr>> { + attrs: ThinAttributes) -> PResult<'a, P<Expr>> { let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; @@ -3065,14 +3059,15 @@ impl<'a> Parser<'a> { } // `match` token already eaten - fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> { + fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> { let match_span = self.last_span; let lo = self.last_span.lo; let discriminant = try!(self.parse_expr_res( Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); - if let Err(e) = self.commit_expr_expecting(&*discriminant, token::OpenDelim(token::Brace)) { + if let Err(mut e) = self.commit_expr_expecting(&*discriminant, + token::OpenDelim(token::Brace)) { if self.token == token::Token::Semi { - self.span_note(match_span, "did you mean to remove this `match` keyword?"); + e.span_note(match_span, "did you mean to remove this `match` keyword?"); } return Err(e) } @@ -3087,7 +3082,7 @@ impl<'a> Parser<'a> { return Ok(self.mk_expr(lo, hi, ExprMatch(discriminant, arms), attrs)); } - pub fn parse_arm(&mut self) -> PResult<Arm> { + pub fn parse_arm(&mut self) -> PResult<'a, Arm> { maybe_whole!(no_clone self, NtArm); let attrs = try!(self.parse_outer_attributes()); @@ -3118,15 +3113,16 @@ impl<'a> Parser<'a> { } /// Parse an expression - pub fn parse_expr(&mut self) -> PResult<P<Expr>> { + pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> { self.parse_expr_res(Restrictions::empty(), None) } /// Evaluate the closure with restrictions in place. /// /// After the closure is evaluated, restrictions are reset. - pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<P<Expr>> - where F: FnOnce(&mut Self) -> PResult<P<Expr>> { + pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<'a, P<Expr>> + where F: FnOnce(&mut Self) -> PResult<'a, P<Expr>> + { let old = self.restrictions; self.restrictions = r; let r = f(self); @@ -3138,12 +3134,12 @@ impl<'a> Parser<'a> { /// Parse an expression, subject to the given restrictions pub fn parse_expr_res(&mut self, r: Restrictions, already_parsed_attrs: Option<ThinAttributes>) - -> PResult<P<Expr>> { + -> PResult<'a, P<Expr>> { self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs)) } /// Parse the RHS of a local variable declaration (e.g. '= 14;') - fn parse_initializer(&mut self) -> PResult<Option<P<Expr>>> { + fn parse_initializer(&mut self) -> PResult<'a, Option<P<Expr>>> { if self.check(&token::Eq) { try!(self.bump()); Ok(Some(try!(self.parse_expr()))) @@ -3153,7 +3149,7 @@ impl<'a> Parser<'a> { } /// Parse patterns, separated by '|' s - fn parse_pats(&mut self) -> PResult<Vec<P<Pat>>> { + fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> { let mut pats = Vec::new(); loop { pats.push(try!(self.parse_pat())); @@ -3162,7 +3158,7 @@ impl<'a> Parser<'a> { }; } - fn parse_pat_tuple_elements(&mut self) -> PResult<Vec<P<Pat>>> { + fn parse_pat_tuple_elements(&mut self) -> PResult<'a, Vec<P<Pat>>> { let mut fields = vec![]; if !self.check(&token::CloseDelim(token::Paren)) { fields.push(try!(self.parse_pat())); @@ -3181,7 +3177,7 @@ impl<'a> Parser<'a> { fn parse_pat_vec_elements( &mut self, - ) -> PResult<(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> { + ) -> PResult<'a, (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> { let mut before = Vec::new(); let mut slice = None; let mut after = Vec::new(); @@ -3233,7 +3229,7 @@ impl<'a> Parser<'a> { } /// Parse the fields of a struct-like pattern - fn parse_pat_fields(&mut self) -> PResult<(Vec<codemap::Spanned<ast::FieldPat>> , bool)> { + fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>> , bool)> { let mut fields = Vec::new(); let mut etc = false; let mut first = true; @@ -3310,7 +3306,7 @@ impl<'a> Parser<'a> { return Ok((fields, etc)); } - fn parse_pat_range_end(&mut self) -> PResult<P<Expr>> { + fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> { if self.is_path_start() { let lo = self.span.lo; let (qself, path) = if try!(self.eat_lt()) { @@ -3336,7 +3332,7 @@ impl<'a> Parser<'a> { } /// Parse a pattern. - pub fn parse_pat(&mut self) -> PResult<P<Pat>> { + pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> { maybe_whole!(self, NtPat); let lo = self.span.lo; @@ -3496,7 +3492,7 @@ impl<'a> Parser<'a> { /// error message when parsing mistakes like ref foo(a,b) fn parse_pat_ident(&mut self, binding_mode: ast::BindingMode) - -> PResult<ast::Pat_> { + -> PResult<'a, ast::Pat_> { if !self.token.is_plain_ident() { let span = self.span; let tok_str = self.this_token_to_string(); @@ -3529,7 +3525,7 @@ impl<'a> Parser<'a> { } /// Parse a local variable declaration - fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<P<Local>> { + fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Local>> { let lo = self.span.lo; let pat = try!(self.parse_pat()); @@ -3549,7 +3545,7 @@ impl<'a> Parser<'a> { } /// Parse a "let" stmt - fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<P<Decl>> { + fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Decl>> { let lo = self.span.lo; let local = try!(self.parse_local(attrs)); Ok(P(spanned(lo, self.last_span.hi, DeclLocal(local)))) @@ -3557,7 +3553,7 @@ impl<'a> Parser<'a> { /// Parse a structure field fn parse_name_and_ty(&mut self, pr: Visibility, - attrs: Vec<Attribute> ) -> PResult<StructField> { + attrs: Vec<Attribute> ) -> PResult<'a, StructField> { let lo = match pr { Inherited => self.span.lo, Public => self.last_span.lo, @@ -3589,11 +3585,11 @@ impl<'a> Parser<'a> { } /// Parse a statement. may include decl. - pub fn parse_stmt(&mut self) -> PResult<Option<P<Stmt>>> { + pub fn parse_stmt(&mut self) -> PResult<'a, Option<P<Stmt>>> { Ok(try!(self.parse_stmt_()).map(P)) } - fn parse_stmt_(&mut self) -> PResult<Option<Stmt>> { + fn parse_stmt_(&mut self) -> PResult<'a, Option<Stmt>> { maybe_whole!(Some deref self, NtStmt); let attrs = try!(self.parse_outer_attributes()); @@ -3729,7 +3725,7 @@ impl<'a> Parser<'a> { } /// Parse a block. No inner attrs are allowed. - pub fn parse_block(&mut self) -> PResult<P<Block>> { + pub fn parse_block(&mut self) -> PResult<'a, P<Block>> { maybe_whole!(no_clone self, NtBlock); let lo = self.span.lo; @@ -3746,7 +3742,7 @@ impl<'a> Parser<'a> { } /// Parse a block. Inner attrs are allowed. - fn parse_inner_attrs_and_block(&mut self) -> PResult<(Vec<Attribute>, P<Block>)> { + fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec<Attribute>, P<Block>)> { maybe_whole!(pair_empty self, NtBlock); let lo = self.span.lo; @@ -3757,7 +3753,7 @@ impl<'a> Parser<'a> { /// Parse the rest of a block expression or function body /// Precondition: already parsed the '{'. - fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<P<Block>> { + fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P<Block>> { let mut stmts = vec![]; let mut expr = None; @@ -3851,7 +3847,7 @@ impl<'a> Parser<'a> { e: P<Expr>, span: Span, stmts: &mut Vec<P<Stmt>>, - last_block_expr: &mut Option<P<Expr>>) -> PResult<()> { + last_block_expr: &mut Option<P<Expr>>) -> PResult<'a, ()> { // expression without semicolon if classify::expr_requires_semi_to_be_stmt(&*e) { // Just check for errors and recover; do not eat semicolon yet. @@ -3887,7 +3883,7 @@ impl<'a> Parser<'a> { // otherwise returns empty list. fn parse_colon_then_ty_param_bounds(&mut self, mode: BoundParsingMode) - -> PResult<TyParamBounds> + -> PResult<'a, TyParamBounds> { if !try!(self.eat(&token::Colon) ){ Ok(P::empty()) @@ -3902,7 +3898,7 @@ impl<'a> Parser<'a> { // and bound = 'region | trait_ref fn parse_ty_param_bounds(&mut self, mode: BoundParsingMode) - -> PResult<TyParamBounds> + -> PResult<'a, TyParamBounds> { let mut result = vec!(); loop { @@ -3948,7 +3944,7 @@ impl<'a> Parser<'a> { } /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )? - fn parse_ty_param(&mut self) -> PResult<TyParam> { + fn parse_ty_param(&mut self) -> PResult<'a, TyParam> { let span = self.span; let ident = try!(self.parse_ident()); @@ -3977,7 +3973,7 @@ impl<'a> Parser<'a> { /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > ) /// | ( < lifetimes , typaramseq ( , )? > ) /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) - pub fn parse_generics(&mut self) -> PResult<ast::Generics> { + pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> { maybe_whole!(self, NtGenerics); if try!(self.eat(&token::Lt) ){ @@ -4008,7 +4004,7 @@ impl<'a> Parser<'a> { } } - fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>, + fn parse_generic_values_after_lt(&mut self) -> PResult<'a, (Vec<ast::Lifetime>, Vec<P<Ty>>, Vec<P<TypeBinding>>)> { let span_lo = self.span.lo; @@ -4025,7 +4021,7 @@ impl<'a> Parser<'a> { let msg = format!("expected `,` or `>` after lifetime \ name, found `{}`", self.this_token_to_string()); - self.span_err(self.span, &msg); + let mut err = self.diagnostic().struct_span_err(self.span, &msg); let span_hi = self.span.hi; let span_hi = if self.parse_ty().is_ok() { @@ -4037,7 +4033,8 @@ impl<'a> Parser<'a> { let msg = format!("did you mean a single argument type &'a Type, \ or did you mean the comma-separated arguments \ 'a, Type?"); - self.span_note(mk_sp(span_lo, span_hi), &msg); + err.span_note(mk_sp(span_lo, span_hi), &msg); + err.emit(); self.abort_if_errors() } @@ -4085,7 +4082,7 @@ impl<'a> Parser<'a> { Ok((lifetimes, types.into_vec(), bindings.into_vec())) } - fn forbid_lifetime(&mut self) -> PResult<()> { + fn forbid_lifetime(&mut self) -> PResult<'a, ()> { if self.token.is_lifetime() { let span = self.span; return Err(self.span_fatal(span, "lifetime parameters must be declared \ @@ -4099,7 +4096,7 @@ impl<'a> Parser<'a> { /// ```ignore /// where T : Trait<U, V> + 'b, 'a : 'b /// ``` - pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> { + pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> { maybe_whole!(self, NtWhereClause); let mut where_clause = WhereClause { @@ -4215,7 +4212,7 @@ impl<'a> Parser<'a> { } fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) - -> PResult<(Vec<Arg> , bool)> { + -> PResult<'a, (Vec<Arg> , bool)> { let sp = self.span; let mut args: Vec<Option<Arg>> = try!(self.parse_unspanned_seq( @@ -4264,7 +4261,7 @@ impl<'a> Parser<'a> { } /// Parse the argument list and result type of a function declaration - pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<P<FnDecl>> { + pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> { let (args, variadic) = try!(self.parse_fn_args(true, allow_variadic)); let ret_ty = try!(self.parse_ret_ty()); @@ -4283,7 +4280,7 @@ impl<'a> Parser<'a> { } } - fn expect_self_ident(&mut self) -> PResult<ast::Ident> { + fn expect_self_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { token::Ident(id, token::Plain) if id.name == special_idents::self_.name => { try!(self.bump()); @@ -4304,7 +4301,7 @@ impl<'a> Parser<'a> { } } - fn expect_self_type_ident(&mut self) -> PResult<ast::Ident> { + fn expect_self_type_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { token::Ident(id, token::Plain) if id.name == special_idents::type_self.name => { try!(self.bump()); @@ -4321,11 +4318,11 @@ impl<'a> Parser<'a> { /// Parse the argument list and result type of a function /// that may have a self type. fn parse_fn_decl_with_self<F>(&mut self, - parse_arg_fn: F) -> PResult<(ExplicitSelf, P<FnDecl>)> where - F: FnMut(&mut Parser) -> PResult<Arg>, + parse_arg_fn: F) -> PResult<'a, (ExplicitSelf, P<FnDecl>)> where + F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, { - fn maybe_parse_borrowed_explicit_self(this: &mut Parser) - -> PResult<ast::ExplicitSelf_> { + fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>) + -> PResult<'b, ast::ExplicitSelf_> { // The following things are possible to see here: // // fn(&mut self) @@ -4483,7 +4480,7 @@ impl<'a> Parser<'a> { } // parse the |arg, arg| header on a lambda - fn parse_fn_block_decl(&mut self) -> PResult<P<FnDecl>> { + fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> { let inputs_captures = { if try!(self.eat(&token::OrOr) ){ Vec::new() @@ -4509,7 +4506,7 @@ impl<'a> Parser<'a> { } /// Parse the name and optional generic types of a function header. - fn parse_fn_header(&mut self) -> PResult<(Ident, ast::Generics)> { + fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> { let id = try!(self.parse_ident()); let generics = try!(self.parse_generics()); Ok((id, generics)) @@ -4533,7 +4530,7 @@ impl<'a> Parser<'a> { unsafety: Unsafety, constness: Constness, abi: abi::Abi) - -> PResult<ItemInfo> { + -> PResult<'a, ItemInfo> { let (ident, mut generics) = try!(self.parse_fn_header()); let decl = try!(self.parse_fn_decl(false)); generics.where_clause = try!(self.parse_where_clause()); @@ -4556,7 +4553,8 @@ impl<'a> Parser<'a> { /// - `const unsafe fn` /// - `extern fn` /// - etc - pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafety, abi::Abi)> { + pub fn parse_fn_front_matter(&mut self) + -> PResult<'a, (ast::Constness, ast::Unsafety, abi::Abi)> { let is_const_fn = try!(self.eat_keyword(keywords::Const)); let unsafety = try!(self.parse_unsafety()); let (constness, unsafety, abi) = if is_const_fn { @@ -4574,7 +4572,7 @@ impl<'a> Parser<'a> { } /// Parse an impl item. - pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> { + pub fn parse_impl_item(&mut self) -> PResult<'a, P<ImplItem>> { maybe_whole!(no_clone self, NtImplItem); let mut attrs = try!(self.parse_outer_attributes()); @@ -4614,9 +4612,10 @@ impl<'a> Parser<'a> { fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) { match visa { Public => { - self.span_err(span, "can't qualify macro invocation with `pub`"); - self.fileline_help(span, "try adjusting the macro to put `pub` inside \ - the invocation"); + self.diagnostic().struct_span_err(span, "can't qualify macro invocation with `pub`") + .fileline_help(span, "try adjusting the macro to put `pub` inside \ + the invocation") + .emit(); } Inherited => (), } @@ -4624,7 +4623,7 @@ impl<'a> Parser<'a> { /// Parse a method or a macro invocation in a trait impl. fn parse_impl_method(&mut self, vis: Visibility) - -> PResult<(Ident, Vec<ast::Attribute>, ast::ImplItemKind)> { + -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> { // code copied from parse_macro_use_or_failure... abstraction! if !self.token.is_any_keyword() && self.look_ahead(1, |t| *t == token::Not) @@ -4673,7 +4672,7 @@ impl<'a> Parser<'a> { } /// Parse trait Foo { ... } - fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<ItemInfo> { + fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> { let ident = try!(self.parse_ident()); let mut tps = try!(self.parse_generics()); @@ -4691,7 +4690,7 @@ impl<'a> Parser<'a> { /// impl<T> Foo { ... } /// impl<T> ToString for &'static T { ... } /// impl Send for .. {} - fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<ItemInfo> { + fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> { let impl_span = self.span; // First, parse type parameters if necessary. @@ -4769,14 +4768,14 @@ impl<'a> Parser<'a> { } /// Parse a::B<String,i32> - fn parse_trait_ref(&mut self) -> PResult<TraitRef> { + fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> { Ok(ast::TraitRef { path: try!(self.parse_path(LifetimeAndTypesWithoutColons)), ref_id: ast::DUMMY_NODE_ID, }) } - fn parse_late_bound_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> { + fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> { if try!(self.eat_keyword(keywords::For) ){ try!(self.expect(&token::Lt)); let lifetime_defs = try!(self.parse_lifetime_defs()); @@ -4788,7 +4787,7 @@ impl<'a> Parser<'a> { } /// Parse for<'l> a::B<String,i32> - fn parse_poly_trait_ref(&mut self) -> PResult<PolyTraitRef> { + fn parse_poly_trait_ref(&mut self) -> PResult<'a, PolyTraitRef> { let lo = self.span.lo; let lifetime_defs = try!(self.parse_late_bound_lifetime_defs()); @@ -4800,7 +4799,7 @@ impl<'a> Parser<'a> { } /// Parse struct Foo { ... } - fn parse_item_struct(&mut self) -> PResult<ItemInfo> { + fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> { let class_name = try!(self.parse_ident()); let mut generics = try!(self.parse_generics()); @@ -4851,7 +4850,9 @@ impl<'a> Parser<'a> { Ok((class_name, ItemStruct(vdata, generics), None)) } - pub fn parse_record_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<StructField>> { + pub fn parse_record_struct_body(&mut self, + parse_pub: ParsePub) + -> PResult<'a, Vec<StructField>> { let mut fields = Vec::new(); if try!(self.eat(&token::OpenDelim(token::Brace)) ){ while self.token != token::CloseDelim(token::Brace) { @@ -4869,7 +4870,9 @@ impl<'a> Parser<'a> { Ok(fields) } - pub fn parse_tuple_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<StructField>> { + pub fn parse_tuple_struct_body(&mut self, + parse_pub: ParsePub) + -> PResult<'a, Vec<StructField>> { // This is the case where we find `struct Foo<T>(T) where T: Copy;` // Unit like structs are handled in parse_item_struct function let fields = try!(self.parse_unspanned_seq( @@ -4901,7 +4904,7 @@ impl<'a> Parser<'a> { pub fn parse_single_struct_field(&mut self, vis: Visibility, attrs: Vec<Attribute> ) - -> PResult<StructField> { + -> PResult<'a, StructField> { let a_var = try!(self.parse_name_and_ty(vis, attrs)); match self.token { token::Comma => { @@ -4921,7 +4924,7 @@ impl<'a> Parser<'a> { } /// Parse an element of a struct definition - fn parse_struct_decl_field(&mut self, parse_pub: ParsePub) -> PResult<StructField> { + fn parse_struct_decl_field(&mut self, parse_pub: ParsePub) -> PResult<'a, StructField> { let attrs = try!(self.parse_outer_attributes()); @@ -4937,13 +4940,13 @@ impl<'a> Parser<'a> { } /// Parse visibility: PUB or nothing - fn parse_visibility(&mut self) -> PResult<Visibility> { + fn parse_visibility(&mut self) -> PResult<'a, Visibility> { if try!(self.eat_keyword(keywords::Pub)) { Ok(Public) } else { Ok(Inherited) } } /// Given a termination token, parse all of the items in a module - fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult<Mod> { + fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult<'a, Mod> { let mut items = vec![]; while let Some(item) = try!(self.parse_item()) { items.push(item); @@ -4966,7 +4969,7 @@ impl<'a> Parser<'a> { }) } - fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<ItemInfo> { + fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> { let id = try!(self.parse_ident()); try!(self.expect(&token::Colon)); let ty = try!(self.parse_ty_sum()); @@ -4981,7 +4984,7 @@ impl<'a> Parser<'a> { } /// Parse a `mod <foo> { ... }` or `mod <foo>;` item - fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<ItemInfo> { + fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> { let id_span = self.span; let id = try!(self.parse_ident()); if self.check(&token::Semi) { @@ -5060,7 +5063,7 @@ impl<'a> Parser<'a> { fn submod_path(&mut self, id: ast::Ident, outer_attrs: &[ast::Attribute], - id_sp: Span) -> PResult<ModulePathSuccess> { + id_sp: Span) -> PResult<'a, ModulePathSuccess> { let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span)); prefix.pop(); let mut dir_path = prefix; @@ -5075,21 +5078,23 @@ impl<'a> Parser<'a> { let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap()); if !self.owns_directory { - self.span_err(id_sp, "cannot declare a new module at this location"); + let mut err = self.diagnostic().struct_span_err(id_sp, + "cannot declare a new module at this location"); let this_module = match self.mod_path_stack.last() { Some(name) => name.to_string(), None => self.root_module_name.as_ref().unwrap().clone(), }; - self.span_note(id_sp, - &format!("maybe move this module `{0}` to its own directory \ + err.span_note(id_sp, + &format!("maybe move this module `{0}` to its own directory \ via `{0}/mod.rs`", this_module)); if paths.path_exists { - self.span_note(id_sp, - &format!("... or maybe `use` the module `{}` instead \ - of possibly redeclaring it", - paths.name)); + err.span_note(id_sp, + &format!("... or maybe `use` the module `{}` instead \ + of possibly redeclaring it", + paths.name)); } + err.emit(); self.abort_if_errors(); } @@ -5104,7 +5109,7 @@ impl<'a> Parser<'a> { id: ast::Ident, outer_attrs: &[ast::Attribute], id_sp: Span) - -> PResult<(ast::Item_, Vec<ast::Attribute> )> { + -> PResult<'a, (ast::Item_, Vec<ast::Attribute> )> { let ModulePathSuccess { path, owns_directory } = try!(self.submod_path(id, outer_attrs, id_sp)); @@ -5119,7 +5124,7 @@ impl<'a> Parser<'a> { path: PathBuf, owns_directory: bool, name: String, - id_sp: Span) -> PResult<(ast::Item_, Vec<ast::Attribute> )> { + id_sp: Span) -> PResult<'a, (ast::Item_, Vec<ast::Attribute> )> { let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); match included_mod_stack.iter().position(|p| *p == path) { Some(i) => { @@ -5152,7 +5157,7 @@ impl<'a> Parser<'a> { /// Parse a function declaration from a foreign module fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: BytePos, - attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> { + attrs: Vec<Attribute>) -> PResult<'a, P<ForeignItem>> { try!(self.expect_keyword(keywords::Fn)); let (ident, mut generics) = try!(self.parse_fn_header()); @@ -5172,7 +5177,7 @@ impl<'a> Parser<'a> { /// Parse a static item from a foreign module fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: BytePos, - attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> { + attrs: Vec<Attribute>) -> PResult<'a, P<ForeignItem>> { try!(self.expect_keyword(keywords::Static)); let mutbl = try!(self.eat_keyword(keywords::Mut)); @@ -5201,7 +5206,7 @@ impl<'a> Parser<'a> { lo: BytePos, visibility: Visibility, attrs: Vec<Attribute>) - -> PResult<P<Item>> { + -> PResult<'a, P<Item>> { let crate_name = try!(self.parse_ident()); let (maybe_path, ident) = if let Some(ident) = try!(self.parse_rename()) { @@ -5242,7 +5247,7 @@ impl<'a> Parser<'a> { opt_abi: Option<abi::Abi>, visibility: Visibility, mut attrs: Vec<Attribute>) - -> PResult<P<Item>> { + -> PResult<'a, P<Item>> { try!(self.expect(&token::OpenDelim(token::Brace))); let abi = opt_abi.unwrap_or(abi::C); @@ -5269,7 +5274,7 @@ impl<'a> Parser<'a> { } /// Parse type Foo = Bar; - fn parse_item_type(&mut self) -> PResult<ItemInfo> { + fn parse_item_type(&mut self) -> PResult<'a, ItemInfo> { let ident = try!(self.parse_ident()); let mut tps = try!(self.parse_generics()); tps.where_clause = try!(self.parse_where_clause()); @@ -5280,7 +5285,7 @@ impl<'a> Parser<'a> { } /// Parse the part of an "enum" decl following the '{' - fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> { + fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> { let mut variants = Vec::new(); let mut all_nullary = true; let mut any_disr = None; @@ -5330,7 +5335,7 @@ impl<'a> Parser<'a> { } /// Parse an "enum" declaration - fn parse_item_enum(&mut self) -> PResult<ItemInfo> { + fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> { let id = try!(self.parse_ident()); let mut generics = try!(self.parse_generics()); generics.where_clause = try!(self.parse_where_clause()); @@ -5342,7 +5347,7 @@ impl<'a> Parser<'a> { /// Parses a string as an ABI spec on an extern type or module. Consumes /// the `extern` keyword, if one is found. - fn parse_opt_abi(&mut self) -> PResult<Option<abi::Abi>> { + fn parse_opt_abi(&mut self) -> PResult<'a, Option<abi::Abi>> { match self.token { token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => { let sp = self.span; @@ -5371,7 +5376,7 @@ impl<'a> Parser<'a> { /// NB: this function no longer parses the items inside an /// extern crate. fn parse_item_(&mut self, attrs: Vec<Attribute>, - macros_allowed: bool, attributes_allowed: bool) -> PResult<Option<P<Item>>> { + macros_allowed: bool, attributes_allowed: bool) -> PResult<'a, Option<P<Item>>> { let nt_item = match self.token { token::Interpolated(token::NtItem(ref item)) => { Some((**item).clone()) @@ -5474,8 +5479,9 @@ impl<'a> Parser<'a> { // CONST ITEM if try!(self.eat_keyword(keywords::Mut) ){ let last_span = self.last_span; - self.span_err(last_span, "const globals cannot be mutable"); - self.fileline_help(last_span, "did you mean to declare a static?"); + self.diagnostic().struct_span_err(last_span, "const globals cannot be mutable") + .fileline_help(last_span, "did you mean to declare a static?") + .emit(); } let (ident, item_, extra_attrs) = try!(self.parse_item_const(None)); let last_span = self.last_span; @@ -5633,7 +5639,7 @@ impl<'a> Parser<'a> { } /// Parse a foreign item. - fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> { + fn parse_foreign_item(&mut self) -> PResult<'a, Option<P<ForeignItem>>> { let attrs = try!(self.parse_outer_attributes()); let lo = self.span.lo; let visibility = try!(self.parse_visibility()); @@ -5664,7 +5670,7 @@ impl<'a> Parser<'a> { attributes_allowed: bool, lo: BytePos, visibility: Visibility - ) -> PResult<Option<P<Item>>> { + ) -> PResult<'a, Option<P<Item>>> { if macros_allowed && !self.token.is_any_keyword() && self.look_ahead(1, |t| *t == token::Not) && (self.look_ahead(2, |t| t.is_plain_ident()) @@ -5736,7 +5742,7 @@ impl<'a> Parser<'a> { Ok(None) } - pub fn parse_item(&mut self) -> PResult<Option<P<Item>>> { + pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> { let attrs = try!(self.parse_outer_attributes()); self.parse_item_(attrs, true, false) } @@ -5747,7 +5753,7 @@ impl<'a> Parser<'a> { /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE /// | MOD? non_global_path MOD_SEP STAR /// | MOD? non_global_path - fn parse_view_path(&mut self) -> PResult<P<ViewPath>> { + fn parse_view_path(&mut self) -> PResult<'a, P<ViewPath>> { let lo = self.span.lo; // Allow a leading :: because the paths are absolute either way. @@ -5843,7 +5849,7 @@ impl<'a> Parser<'a> { Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))) } - fn parse_rename(&mut self) -> PResult<Option<Ident>> { + fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> { if try!(self.eat_keyword(keywords::As)) { self.parse_ident().map(Some) } else { @@ -5853,7 +5859,7 @@ impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main /// entry point for the parser. - pub fn parse_crate_mod(&mut self) -> PResult<Crate> { + pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> { let lo = self.span.lo; Ok(ast::Crate { attrs: try!(self.parse_inner_attributes()), @@ -5865,7 +5871,7 @@ impl<'a> Parser<'a> { } pub fn parse_optional_str(&mut self) - -> PResult<Option<(InternedString, + -> PResult<'a, Option<(InternedString, ast::StrStyle, Option<ast::Name>)>> { let ret = match self.token { @@ -5881,7 +5887,7 @@ impl<'a> Parser<'a> { Ok(Some(ret)) } - pub fn parse_str(&mut self) -> PResult<(InternedString, StrStyle)> { + pub fn parse_str(&mut self) -> PResult<'a, (InternedString, StrStyle)> { match try!(self.parse_optional_str()) { Some((s, style, suf)) => { let sp = self.last_span; diff --git a/src/libsyntax/show_span.rs b/src/libsyntax/show_span.rs index 014c7b2a68f..5e3cd0773aa 100644 --- a/src/libsyntax/show_span.rs +++ b/src/libsyntax/show_span.rs @@ -47,21 +47,21 @@ struct ShowSpanVisitor<'a> { impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> { fn visit_expr(&mut self, e: &ast::Expr) { if let Mode::Expression = self.mode { - self.span_diagnostic.span_note(e.span, "expression"); + self.span_diagnostic.span_warn(e.span, "expression"); } visit::walk_expr(self, e); } fn visit_pat(&mut self, p: &ast::Pat) { if let Mode::Pattern = self.mode { - self.span_diagnostic.span_note(p.span, "pattern"); + self.span_diagnostic.span_warn(p.span, "pattern"); } visit::walk_pat(self, p); } fn visit_ty(&mut self, t: &ast::Ty) { if let Mode::Type = self.mode { - self.span_diagnostic.span_note(t.span, "type"); + self.span_diagnostic.span_warn(t.span, "type"); } visit::walk_ty(self, t); } diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index a462dbeb6e4..454b925a494 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -30,10 +30,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> source_str) } -fn with_error_checking_parse<T, F>(s: String, f: F) -> T where - F: FnOnce(&mut Parser) -> PResult<T>, +fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where + F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>, { - let ps = ParseSess::new(); let mut p = string_to_parser(&ps, s); let x = panictry!(f(&mut p)); p.abort_if_errors(); @@ -42,28 +41,32 @@ fn with_error_checking_parse<T, F>(s: String, f: F) -> T where /// Parse a string, return a crate. pub fn string_to_crate (source_str : String) -> ast::Crate { - with_error_checking_parse(source_str, |p| { + let ps = ParseSess::new(); + with_error_checking_parse(source_str, &ps, |p| { p.parse_crate_mod() }) } /// Parse a string, return an expr pub fn string_to_expr (source_str : String) -> P<ast::Expr> { - with_error_checking_parse(source_str, |p| { + let ps = ParseSess::new(); + with_error_checking_parse(source_str, &ps, |p| { p.parse_expr() }) } /// Parse a string, return an item pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> { - with_error_checking_parse(source_str, |p| { + let ps = ParseSess::new(); + with_error_checking_parse(source_str, &ps, |p| { p.parse_item() }) } /// Parse a string, return a stmt pub fn string_to_stmt(source_str : String) -> Option<P<ast::Stmt>> { - with_error_checking_parse(source_str, |p| { + let ps = ParseSess::new(); + with_error_checking_parse(source_str, &ps, |p| { p.parse_stmt() }) } @@ -71,7 +74,8 @@ pub fn string_to_stmt(source_str : String) -> Option<P<ast::Stmt>> { /// Parse a string, return a pat. Uses "irrefutable"... which doesn't /// (currently) affect parsing. pub fn string_to_pat(source_str: String) -> P<ast::Pat> { - with_error_checking_parse(source_str, |p| { + let ps = ParseSess::new(); + with_error_checking_parse(source_str, &ps, |p| { p.parse_pat() }) } |
