about summary refs log tree commit diff
path: root/src/libsyntax/parse/attr.rs
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/parse/attr.rs
parentc141f47c2449a2f70e6d199104eb318b083def2a (diff)
downloadrust-de95857129a8bdcc623f57f669b535ddf8a8db6e.tar.gz
rust-de95857129a8bdcc623f57f669b535ddf8a8db6e.zip
Don't panic for fatal errors in attribute parsing.
Diffstat (limited to 'src/libsyntax/parse/attr.rs')
-rw-r--r--src/libsyntax/parse/attr.rs69
1 files changed, 35 insertions, 34 deletions
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())
     }
 }