mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-04 09:53:04 +03:00
Don't panic for fatal errors in attribute parsing.
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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),
|
||||
|
||||
+35
-34
@@ -12,20 +12,21 @@
|
||||
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 @@ pub fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
|
||||
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 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
|
||||
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 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
|
||||
value: value,
|
||||
is_sugared_doc: false
|
||||
}
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse attributes that appear after the opening of an item. These should
|
||||
@@ -110,7 +111,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
|
||||
/// 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 @@ pub fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
|
||||
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 @@ pub fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
|
||||
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 @@ pub fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
|
||||
_ => 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 @@ pub fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
|
||||
|
||||
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 @@ pub fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
|
||||
}
|
||||
}
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1174,7 +1174,7 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
|
||||
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 @@ fn parse_match_expr(&mut self) -> PResult<P<Expr>> {
|
||||
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 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn parse_inner_attrs_and_block(&mut self) -> PResult<(Vec<Attribute>, P<Block>)>
|
||||
|
||||
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 @@ pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafet
|
||||
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 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<ItemInfo> {
|
||||
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 @@ pub fn parse_tuple_struct_body(&mut self,
|
||||
&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 @@ pub fn parse_single_struct_field(&mut self,
|
||||
/// 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 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<ItemInfo> {
|
||||
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 @@ fn eval_src_mod_from_path(&mut self,
|
||||
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 @@ fn parse_item_foreign_mod(&mut self,
|
||||
|
||||
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 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
|
||||
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 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
|
||||
|
||||
/// 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 @@ fn parse_macro_use_or_failure(
|
||||
}
|
||||
|
||||
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 @@ fn parse_rename(&mut self) -> PResult<Option<Ident>> {
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user