diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2015-10-23 19:02:38 -0700 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2015-10-27 20:09:10 -0700 |
| commit | de95857129a8bdcc623f57f669b535ddf8a8db6e (patch) | |
| tree | 9b966982e5c9e5d9599e369059303f6457e9971a /src/libsyntax/parse/attr.rs | |
| parent | c141f47c2449a2f70e6d199104eb318b083def2a (diff) | |
| download | rust-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.rs | 69 |
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()) } } |
