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 | |
| 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')
| -rw-r--r-- | src/libsyntax/ext/cfg.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 69 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 30 |
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), |
