about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2015-10-23 19:02:38 -0700
committerEli Friedman <eli.friedman@gmail.com>2015-10-27 20:09:10 -0700
commitde95857129a8bdcc623f57f669b535ddf8a8db6e (patch)
tree9b966982e5c9e5d9599e369059303f6457e9971a /src/libsyntax
parentc141f47c2449a2f70e6d199104eb318b083def2a (diff)
downloadrust-de95857129a8bdcc623f57f669b535ddf8a8db6e.tar.gz
rust-de95857129a8bdcc623f57f669b535ddf8a8db6e.zip
Don't panic for fatal errors in attribute parsing.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/cfg.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs2
-rw-r--r--src/libsyntax/parse/attr.rs69
-rw-r--r--src/libsyntax/parse/mod.rs7
-rw-r--r--src/libsyntax/parse/parser.rs30
5 files changed, 56 insertions, 54 deletions
diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs
index 5074189a048..d354a4ae215 100644
--- a/src/libsyntax/ext/cfg.rs
+++ b/src/libsyntax/ext/cfg.rs
@@ -26,7 +26,7 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
                        tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
     let mut p = cx.new_parser_from_tts(tts);
-    let cfg = p.parse_meta_item();
+    let cfg = panictry!(p.parse_meta_item());
 
     if !panictry!(p.eat(&token::Eof)){
         cx.span_err(sp, "expected 1 cfg-pattern");
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 40a8f1cc6b5..a4c99018bb9 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -526,7 +526,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         "path" => {
             token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
         },
-        "meta" => token::NtMeta(p.parse_meta_item()),
+        "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
         _ => {
             panic!(p.span_fatal_help(sp,
                             &format!("invalid fragment specifier `{}`", name),
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 570c232ff4e..7b96135f1c3 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -12,20 +12,21 @@ use attr;
 use ast;
 use codemap::{spanned, Spanned, mk_sp, Span};
 use parse::common::*; //resolve bug?
+use parse::PResult;
 use parse::token;
 use parse::parser::{Parser, TokenType};
 use ptr::P;
 
 impl<'a> Parser<'a> {
     /// Parse attributes that appear before an item
-    pub fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
+    pub fn parse_outer_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
         loop {
             debug!("parse_outer_attributes: self.token={:?}",
                    self.token);
             match self.token {
               token::Pound => {
-                attrs.push(self.parse_attribute(false));
+                attrs.push(try!(self.parse_attribute(false)));
               }
               token::DocComment(s) => {
                 let attr = ::attr::mk_sugared_doc_attr(
@@ -35,32 +36,32 @@ impl<'a> Parser<'a> {
                     self.span.hi
                 );
                 if attr.node.style != ast::AttrStyle::Outer {
-                  panic!(self.fatal("expected outer comment"));
+                  return Err(self.fatal("expected outer comment"));
                 }
                 attrs.push(attr);
-                panictry!(self.bump());
+                try!(self.bump());
               }
               _ => break
             }
         }
-        return attrs;
+        return Ok(attrs);
     }
 
     /// Matches `attribute = # ! [ meta_item ]`
     ///
     /// If permit_inner is true, then a leading `!` indicates an inner
     /// attribute
-    fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
+    fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute> {
         debug!("parse_attributes: permit_inner={:?} self.token={:?}",
                permit_inner, self.token);
         let (span, value, mut style) = match self.token {
             token::Pound => {
                 let lo = self.span.lo;
-                panictry!(self.bump());
+                try!(self.bump());
 
                 if permit_inner { self.expected_tokens.push(TokenType::Token(token::Not)); }
                 let style = if self.token == token::Not {
-                    panictry!(self.bump());
+                    try!(self.bump());
                     if !permit_inner {
                         let span = self.span;
                         self.span_err(span,
@@ -74,27 +75,27 @@ impl<'a> Parser<'a> {
                     ast::AttrStyle::Outer
                 };
 
-                panictry!(self.expect(&token::OpenDelim(token::Bracket)));
-                let meta_item = self.parse_meta_item();
+                try!(self.expect(&token::OpenDelim(token::Bracket)));
+                let meta_item = try!(self.parse_meta_item());
                 let hi = self.span.hi;
-                panictry!(self.expect(&token::CloseDelim(token::Bracket)));
+                try!(self.expect(&token::CloseDelim(token::Bracket)));
 
                 (mk_sp(lo, hi), meta_item, style)
             }
             _ => {
                 let token_str = self.this_token_to_string();
-                panic!(self.fatal(&format!("expected `#`, found `{}`", token_str)));
+                return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
             }
         };
 
         if permit_inner && self.token == token::Semi {
-            panictry!(self.bump());
+            try!(self.bump());
             self.span_warn(span, "this inner attribute syntax is deprecated. \
                            The new syntax is `#![foo]`, with a bang and no semicolon");
             style = ast::AttrStyle::Inner;
         }
 
-        return Spanned {
+        Ok(Spanned {
             span: span,
             node: ast::Attribute_ {
                 id: attr::mk_attr_id(),
@@ -102,7 +103,7 @@ impl<'a> Parser<'a> {
                 value: value,
                 is_sugared_doc: false
             }
-        };
+        })
     }
 
     /// Parse attributes that appear after the opening of an item. These should
@@ -110,7 +111,7 @@ impl<'a> Parser<'a> {
     /// terminated by a semicolon.
 
     /// matches inner_attrs*
-    pub fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
+    pub fn parse_inner_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
             match self.token {
@@ -120,7 +121,7 @@ impl<'a> Parser<'a> {
                         break;
                     }
 
-                    let attr = self.parse_attribute(true);
+                    let attr = try!(self.parse_attribute(true));
                     assert!(attr.node.style == ast::AttrStyle::Inner);
                     attrs.push(attr);
                 }
@@ -131,7 +132,7 @@ impl<'a> Parser<'a> {
                     let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), str, lo, hi);
                     if attr.node.style == ast::AttrStyle::Inner {
                         attrs.push(attr);
-                        panictry!(self.bump());
+                        try!(self.bump());
                     } else {
                         break;
                     }
@@ -139,13 +140,13 @@ impl<'a> Parser<'a> {
                 _ => break
             }
         }
-        attrs
+        Ok(attrs)
     }
 
     /// matches meta_item = IDENT
     /// | IDENT = lit
     /// | IDENT meta_seq
-    pub fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
+    pub fn parse_meta_item(&mut self) -> PResult<P<ast::MetaItem>> {
         let nt_meta = match self.token {
             token::Interpolated(token::NtMeta(ref e)) => {
                 Some(e.clone())
@@ -155,19 +156,19 @@ impl<'a> Parser<'a> {
 
         match nt_meta {
             Some(meta) => {
-                panictry!(self.bump());
-                return meta;
+                try!(self.bump());
+                return Ok(meta);
             }
             None => {}
         }
 
         let lo = self.span.lo;
-        let ident = panictry!(self.parse_ident());
+        let ident = try!(self.parse_ident());
         let name = self.id_to_interned_str(ident);
         match self.token {
             token::Eq => {
-                panictry!(self.bump());
-                let lit = panictry!(self.parse_lit());
+                try!(self.bump());
+                let lit = try!(self.parse_lit());
                 // FIXME #623 Non-string meta items are not serialized correctly;
                 // just forbid them for now
                 match lit.node {
@@ -179,25 +180,25 @@ impl<'a> Parser<'a> {
                     }
                 }
                 let hi = self.span.hi;
-                P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
+                Ok(P(spanned(lo, hi, ast::MetaNameValue(name, lit))))
             }
             token::OpenDelim(token::Paren) => {
-                let inner_items = self.parse_meta_seq();
+                let inner_items = try!(self.parse_meta_seq());
                 let hi = self.span.hi;
-                P(spanned(lo, hi, ast::MetaList(name, inner_items)))
+                Ok(P(spanned(lo, hi, ast::MetaList(name, inner_items))))
             }
             _ => {
                 let hi = self.last_span.hi;
-                P(spanned(lo, hi, ast::MetaWord(name)))
+                Ok(P(spanned(lo, hi, ast::MetaWord(name))))
             }
         }
     }
 
     /// matches meta_seq = ( COMMASEP(meta_item) )
-    fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
-        panictry!(self.parse_seq(&token::OpenDelim(token::Paren),
-                       &token::CloseDelim(token::Paren),
-                       seq_sep_trailing_allowed(token::Comma),
-                       |p| Ok(p.parse_meta_item()))).node
+    fn parse_meta_seq(&mut self) -> PResult<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())
     }
 }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 017a910b08a..bbecedf92ea 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -82,7 +82,8 @@ pub fn parse_crate_attrs_from_file(
     cfg: ast::CrateConfig,
     sess: &ParseSess
 ) -> Vec<ast::Attribute> {
-    new_parser_from_file(sess, cfg, input).parse_inner_attributes()
+    // FIXME: maybe_aborted?
+    panictry!(new_parser_from_file(sess, cfg, input).parse_inner_attributes())
 }
 
 pub fn parse_crate_from_source_str(name: String,
@@ -106,7 +107,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
                                            cfg,
                                            name,
                                            source);
-    maybe_aborted(p.parse_inner_attributes(), p)
+    maybe_aborted(panictry!(p.parse_inner_attributes()), p)
 }
 
 pub fn parse_expr_from_source_str(name: String,
@@ -133,7 +134,7 @@ pub fn parse_meta_from_source_str(name: String,
                                   sess: &ParseSess)
                                   -> P<ast::MetaItem> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    maybe_aborted(p.parse_meta_item(), p)
+    maybe_aborted(panictry!(p.parse_meta_item()), p)
 }
 
 pub fn parse_stmt_from_source_str(name: String,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 0b2369c00ac..d71ea4d105b 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1174,7 +1174,7 @@ impl<'a> Parser<'a> {
             seq_sep_none(),
             |p| -> PResult<P<TraitItem>> {
             maybe_whole!(no_clone p, NtTraitItem);
-            let mut attrs = p.parse_outer_attributes();
+            let mut attrs = try!(p.parse_outer_attributes());
             let lo = p.span.lo;
 
             let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
@@ -2956,7 +2956,7 @@ impl<'a> Parser<'a> {
     pub fn parse_arm_nopanic(&mut self) -> PResult<Arm> {
         maybe_whole!(no_clone self, NtArm);
 
-        let attrs = self.parse_outer_attributes();
+        let attrs = try!(self.parse_outer_attributes());
         let pats = try!(self.parse_pats());
         let mut guard = None;
         if try!(self.eat_keyword(keywords::If) ){
@@ -3465,7 +3465,7 @@ impl<'a> Parser<'a> {
             }
         }
 
-        let attrs = self.parse_outer_attributes();
+        let attrs = try!(self.parse_outer_attributes());
         let lo = self.span.lo;
 
         Ok(Some(if self.check_keyword(keywords::Let) {
@@ -3607,7 +3607,7 @@ impl<'a> Parser<'a> {
 
         let lo = self.span.lo;
         try!(self.expect(&token::OpenDelim(token::Brace)));
-        Ok((self.parse_inner_attributes(),
+        Ok((try!(self.parse_inner_attributes()),
          try!(self.parse_block_tail(lo, DefaultBlock))))
     }
 
@@ -4431,7 +4431,7 @@ impl<'a> Parser<'a> {
     pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
         maybe_whole!(no_clone self, NtImplItem);
 
-        let mut attrs = self.parse_outer_attributes();
+        let mut attrs = try!(self.parse_outer_attributes());
         let lo = self.span.lo;
         let vis = try!(self.parse_visibility());
         let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
@@ -4608,7 +4608,7 @@ impl<'a> Parser<'a> {
             generics.where_clause = try!(self.parse_where_clause());
 
             try!(self.expect(&token::OpenDelim(token::Brace)));
-            let attrs = self.parse_inner_attributes();
+            let attrs = try!(self.parse_inner_attributes());
 
             let mut impl_items = vec![];
             while !try!(self.eat(&token::CloseDelim(token::Brace))) {
@@ -4727,7 +4727,7 @@ impl<'a> Parser<'a> {
             &token::CloseDelim(token::Paren),
             seq_sep_trailing_allowed(token::Comma),
             |p| {
-                let attrs = p.parse_outer_attributes();
+                let attrs = try!(p.parse_outer_attributes());
                 let lo = p.span.lo;
                 let struct_field_ = ast::StructField_ {
                     kind: UnnamedField(try!(p.parse_visibility())),
@@ -4769,7 +4769,7 @@ impl<'a> Parser<'a> {
     /// Parse an element of a struct definition
     fn parse_struct_decl_field(&mut self, allow_pub: bool) -> PResult<StructField> {
 
-        let attrs = self.parse_outer_attributes();
+        let attrs = try!(self.parse_outer_attributes());
 
         if try!(self.eat_keyword(keywords::Pub) ){
             if !allow_pub {
@@ -4841,7 +4841,7 @@ impl<'a> Parser<'a> {
             let mod_inner_lo = self.span.lo;
             let old_owns_directory = self.owns_directory;
             self.owns_directory = true;
-            let attrs = self.parse_inner_attributes();
+            let attrs = try!(self.parse_inner_attributes());
             let m = try!(self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo));
             self.owns_directory = old_owns_directory;
             self.pop_mod_path();
@@ -4990,7 +4990,7 @@ impl<'a> Parser<'a> {
                                               Some(name),
                                               id_sp);
         let mod_inner_lo = p0.span.lo;
-        let mod_attrs = p0.parse_inner_attributes();
+        let mod_attrs = try!(p0.parse_inner_attributes());
         let m0 = try!(p0.parse_mod_items(&token::Eof, mod_inner_lo));
         self.sess.included_mod_stack.borrow_mut().pop();
         Ok((ast::ItemMod(m0), mod_attrs))
@@ -5093,7 +5093,7 @@ impl<'a> Parser<'a> {
 
         let abi = opt_abi.unwrap_or(abi::C);
 
-        attrs.extend(self.parse_inner_attributes());
+        attrs.extend(try!(self.parse_inner_attributes()));
 
         let mut foreign_items = vec![];
         while let Some(item) = try!(self.parse_foreign_item()) {
@@ -5143,7 +5143,7 @@ impl<'a> Parser<'a> {
         let mut all_nullary = true;
         let mut any_disr = None;
         while self.token != token::CloseDelim(token::Brace) {
-            let variant_attrs = self.parse_outer_attributes();
+            let variant_attrs = try!(self.parse_outer_attributes());
             let vlo = self.span.lo;
 
             let struct_def;
@@ -5505,7 +5505,7 @@ impl<'a> Parser<'a> {
 
     /// Parse a foreign item.
     fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
-        let attrs = self.parse_outer_attributes();
+        let attrs = try!(self.parse_outer_attributes());
         let lo = self.span.lo;
         let visibility = try!(self.parse_visibility());
 
@@ -5605,7 +5605,7 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_item_nopanic(&mut self) -> PResult<Option<P<Item>>> {
-        let attrs = self.parse_outer_attributes();
+        let attrs = try!(self.parse_outer_attributes());
         self.parse_item_(attrs, true)
     }
 
@@ -5724,7 +5724,7 @@ impl<'a> Parser<'a> {
     pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
         let lo = self.span.lo;
         Ok(ast::Crate {
-            attrs: self.parse_inner_attributes(),
+            attrs: try!(self.parse_inner_attributes()),
             module: try!(self.parse_mod_items(&token::Eof, lo)),
             config: self.cfg.clone(),
             span: mk_sp(lo, self.span.lo),