about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-12-21 10:00:43 +1300
committerNick Cameron <ncameron@mozilla.com>2015-12-30 14:27:59 +1300
commit95dc7efad0df3640096a48a84c1d7a29044be750 (patch)
tree0d63c8598508c8892f7e8b84c7ecd242371b27b5 /src/libsyntax/parse
parent253a1cefd8a9db926ca2d983dde5234504c86b4b (diff)
downloadrust-95dc7efad0df3640096a48a84c1d7a29044be750.tar.gz
rust-95dc7efad0df3640096a48a84c1d7a29044be750.zip
use structured errors
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/attr.rs24
-rw-r--r--src/libsyntax/parse/lexer/mod.rs63
-rw-r--r--src/libsyntax/parse/lexer/unicode_chars.rs7
-rw-r--r--src/libsyntax/parse/mod.rs50
-rw-r--r--src/libsyntax/parse/obsolete.rs13
-rw-r--r--src/libsyntax/parse/parser.rs468
6 files changed, 337 insertions, 288 deletions
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..f31f24cf249 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
+        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;