Don't panic for fatal errors in attribute parsing.
This commit is contained in:
parent
c141f47c24
commit
de95857129
5 changed files with 56 additions and 54 deletions
|
@ -26,7 +26,7 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
|
||||||
tts: &[ast::TokenTree])
|
tts: &[ast::TokenTree])
|
||||||
-> Box<base::MacResult+'static> {
|
-> Box<base::MacResult+'static> {
|
||||||
let mut p = cx.new_parser_from_tts(tts);
|
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)){
|
if !panictry!(p.eat(&token::Eof)){
|
||||||
cx.span_err(sp, "expected 1 cfg-pattern");
|
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" => {
|
"path" => {
|
||||||
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
|
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,
|
panic!(p.span_fatal_help(sp,
|
||||||
&format!("invalid fragment specifier `{}`", name),
|
&format!("invalid fragment specifier `{}`", name),
|
||||||
|
|
|
@ -12,20 +12,21 @@ use attr;
|
||||||
use ast;
|
use ast;
|
||||||
use codemap::{spanned, Spanned, mk_sp, Span};
|
use codemap::{spanned, Spanned, mk_sp, Span};
|
||||||
use parse::common::*; //resolve bug?
|
use parse::common::*; //resolve bug?
|
||||||
|
use parse::PResult;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use parse::parser::{Parser, TokenType};
|
use parse::parser::{Parser, TokenType};
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
/// Parse attributes that appear before an item
|
/// 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();
|
let mut attrs: Vec<ast::Attribute> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
debug!("parse_outer_attributes: self.token={:?}",
|
debug!("parse_outer_attributes: self.token={:?}",
|
||||||
self.token);
|
self.token);
|
||||||
match self.token {
|
match self.token {
|
||||||
token::Pound => {
|
token::Pound => {
|
||||||
attrs.push(self.parse_attribute(false));
|
attrs.push(try!(self.parse_attribute(false)));
|
||||||
}
|
}
|
||||||
token::DocComment(s) => {
|
token::DocComment(s) => {
|
||||||
let attr = ::attr::mk_sugared_doc_attr(
|
let attr = ::attr::mk_sugared_doc_attr(
|
||||||
|
@ -35,32 +36,32 @@ impl<'a> Parser<'a> {
|
||||||
self.span.hi
|
self.span.hi
|
||||||
);
|
);
|
||||||
if attr.node.style != ast::AttrStyle::Outer {
|
if attr.node.style != ast::AttrStyle::Outer {
|
||||||
panic!(self.fatal("expected outer comment"));
|
return Err(self.fatal("expected outer comment"));
|
||||||
}
|
}
|
||||||
attrs.push(attr);
|
attrs.push(attr);
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
}
|
}
|
||||||
_ => break
|
_ => break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return attrs;
|
return Ok(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Matches `attribute = # ! [ meta_item ]`
|
/// Matches `attribute = # ! [ meta_item ]`
|
||||||
///
|
///
|
||||||
/// If permit_inner is true, then a leading `!` indicates an inner
|
/// If permit_inner is true, then a leading `!` indicates an inner
|
||||||
/// attribute
|
/// 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={:?}",
|
debug!("parse_attributes: permit_inner={:?} self.token={:?}",
|
||||||
permit_inner, self.token);
|
permit_inner, self.token);
|
||||||
let (span, value, mut style) = match self.token {
|
let (span, value, mut style) = match self.token {
|
||||||
token::Pound => {
|
token::Pound => {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
|
|
||||||
if permit_inner { self.expected_tokens.push(TokenType::Token(token::Not)); }
|
if permit_inner { self.expected_tokens.push(TokenType::Token(token::Not)); }
|
||||||
let style = if self.token == token::Not {
|
let style = if self.token == token::Not {
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
if !permit_inner {
|
if !permit_inner {
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
self.span_err(span,
|
self.span_err(span,
|
||||||
|
@ -74,27 +75,27 @@ impl<'a> Parser<'a> {
|
||||||
ast::AttrStyle::Outer
|
ast::AttrStyle::Outer
|
||||||
};
|
};
|
||||||
|
|
||||||
panictry!(self.expect(&token::OpenDelim(token::Bracket)));
|
try!(self.expect(&token::OpenDelim(token::Bracket)));
|
||||||
let meta_item = self.parse_meta_item();
|
let meta_item = try!(self.parse_meta_item());
|
||||||
let hi = self.span.hi;
|
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)
|
(mk_sp(lo, hi), meta_item, style)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let token_str = self.this_token_to_string();
|
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 {
|
if permit_inner && self.token == token::Semi {
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
self.span_warn(span, "this inner attribute syntax is deprecated. \
|
self.span_warn(span, "this inner attribute syntax is deprecated. \
|
||||||
The new syntax is `#![foo]`, with a bang and no semicolon");
|
The new syntax is `#![foo]`, with a bang and no semicolon");
|
||||||
style = ast::AttrStyle::Inner;
|
style = ast::AttrStyle::Inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Spanned {
|
Ok(Spanned {
|
||||||
span: span,
|
span: span,
|
||||||
node: ast::Attribute_ {
|
node: ast::Attribute_ {
|
||||||
id: attr::mk_attr_id(),
|
id: attr::mk_attr_id(),
|
||||||
|
@ -102,7 +103,7 @@ impl<'a> Parser<'a> {
|
||||||
value: value,
|
value: value,
|
||||||
is_sugared_doc: false
|
is_sugared_doc: false
|
||||||
}
|
}
|
||||||
};
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse attributes that appear after the opening of an item. These should
|
/// Parse attributes that appear after the opening of an item. These should
|
||||||
|
@ -110,7 +111,7 @@ impl<'a> Parser<'a> {
|
||||||
/// terminated by a semicolon.
|
/// terminated by a semicolon.
|
||||||
|
|
||||||
/// matches inner_attrs*
|
/// 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![];
|
let mut attrs: Vec<ast::Attribute> = vec![];
|
||||||
loop {
|
loop {
|
||||||
match self.token {
|
match self.token {
|
||||||
|
@ -120,7 +121,7 @@ impl<'a> Parser<'a> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let attr = self.parse_attribute(true);
|
let attr = try!(self.parse_attribute(true));
|
||||||
assert!(attr.node.style == ast::AttrStyle::Inner);
|
assert!(attr.node.style == ast::AttrStyle::Inner);
|
||||||
attrs.push(attr);
|
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);
|
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), str, lo, hi);
|
||||||
if attr.node.style == ast::AttrStyle::Inner {
|
if attr.node.style == ast::AttrStyle::Inner {
|
||||||
attrs.push(attr);
|
attrs.push(attr);
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -139,13 +140,13 @@ impl<'a> Parser<'a> {
|
||||||
_ => break
|
_ => break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attrs
|
Ok(attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// matches meta_item = IDENT
|
/// matches meta_item = IDENT
|
||||||
/// | IDENT = lit
|
/// | IDENT = lit
|
||||||
/// | IDENT meta_seq
|
/// | 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 {
|
let nt_meta = match self.token {
|
||||||
token::Interpolated(token::NtMeta(ref e)) => {
|
token::Interpolated(token::NtMeta(ref e)) => {
|
||||||
Some(e.clone())
|
Some(e.clone())
|
||||||
|
@ -155,19 +156,19 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
match nt_meta {
|
match nt_meta {
|
||||||
Some(meta) => {
|
Some(meta) => {
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
return meta;
|
return Ok(meta);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lo = self.span.lo;
|
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);
|
let name = self.id_to_interned_str(ident);
|
||||||
match self.token {
|
match self.token {
|
||||||
token::Eq => {
|
token::Eq => {
|
||||||
panictry!(self.bump());
|
try!(self.bump());
|
||||||
let lit = panictry!(self.parse_lit());
|
let lit = try!(self.parse_lit());
|
||||||
// FIXME #623 Non-string meta items are not serialized correctly;
|
// FIXME #623 Non-string meta items are not serialized correctly;
|
||||||
// just forbid them for now
|
// just forbid them for now
|
||||||
match lit.node {
|
match lit.node {
|
||||||
|
@ -179,25 +180,25 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let hi = self.span.hi;
|
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) => {
|
token::OpenDelim(token::Paren) => {
|
||||||
let inner_items = self.parse_meta_seq();
|
let inner_items = try!(self.parse_meta_seq());
|
||||||
let hi = self.span.hi;
|
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;
|
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) )
|
/// matches meta_seq = ( COMMASEP(meta_item) )
|
||||||
fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
|
fn parse_meta_seq(&mut self) -> PResult<Vec<P<ast::MetaItem>>> {
|
||||||
panictry!(self.parse_seq(&token::OpenDelim(token::Paren),
|
self.parse_unspanned_seq(&token::OpenDelim(token::Paren),
|
||||||
&token::CloseDelim(token::Paren),
|
&token::CloseDelim(token::Paren),
|
||||||
seq_sep_trailing_allowed(token::Comma),
|
seq_sep_trailing_allowed(token::Comma),
|
||||||
|p| Ok(p.parse_meta_item()))).node
|
|p| p.parse_meta_item())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,8 @@ pub fn parse_crate_attrs_from_file(
|
||||||
cfg: ast::CrateConfig,
|
cfg: ast::CrateConfig,
|
||||||
sess: &ParseSess
|
sess: &ParseSess
|
||||||
) -> Vec<ast::Attribute> {
|
) -> 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,
|
pub fn parse_crate_from_source_str(name: String,
|
||||||
|
@ -106,7 +107,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
|
||||||
cfg,
|
cfg,
|
||||||
name,
|
name,
|
||||||
source);
|
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,
|
pub fn parse_expr_from_source_str(name: String,
|
||||||
|
@ -133,7 +134,7 @@ pub fn parse_meta_from_source_str(name: String,
|
||||||
sess: &ParseSess)
|
sess: &ParseSess)
|
||||||
-> P<ast::MetaItem> {
|
-> P<ast::MetaItem> {
|
||||||
let mut p = new_parser_from_source_str(sess, cfg, name, source);
|
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,
|
pub fn parse_stmt_from_source_str(name: String,
|
||||||
|
|
|
@ -1174,7 +1174,7 @@ impl<'a> Parser<'a> {
|
||||||
seq_sep_none(),
|
seq_sep_none(),
|
||||||
|p| -> PResult<P<TraitItem>> {
|
|p| -> PResult<P<TraitItem>> {
|
||||||
maybe_whole!(no_clone p, NtTraitItem);
|
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 lo = p.span.lo;
|
||||||
|
|
||||||
let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
|
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> {
|
pub fn parse_arm_nopanic(&mut self) -> PResult<Arm> {
|
||||||
maybe_whole!(no_clone self, NtArm);
|
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 pats = try!(self.parse_pats());
|
||||||
let mut guard = None;
|
let mut guard = None;
|
||||||
if try!(self.eat_keyword(keywords::If) ){
|
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;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
Ok(Some(if self.check_keyword(keywords::Let) {
|
Ok(Some(if self.check_keyword(keywords::Let) {
|
||||||
|
@ -3607,7 +3607,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
try!(self.expect(&token::OpenDelim(token::Brace)));
|
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))))
|
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>> {
|
pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
|
||||||
maybe_whole!(no_clone self, NtImplItem);
|
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 lo = self.span.lo;
|
||||||
let vis = try!(self.parse_visibility());
|
let vis = try!(self.parse_visibility());
|
||||||
let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
|
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());
|
generics.where_clause = try!(self.parse_where_clause());
|
||||||
|
|
||||||
try!(self.expect(&token::OpenDelim(token::Brace)));
|
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![];
|
let mut impl_items = vec![];
|
||||||
while !try!(self.eat(&token::CloseDelim(token::Brace))) {
|
while !try!(self.eat(&token::CloseDelim(token::Brace))) {
|
||||||
|
@ -4727,7 +4727,7 @@ impl<'a> Parser<'a> {
|
||||||
&token::CloseDelim(token::Paren),
|
&token::CloseDelim(token::Paren),
|
||||||
seq_sep_trailing_allowed(token::Comma),
|
seq_sep_trailing_allowed(token::Comma),
|
||||||
|p| {
|
|p| {
|
||||||
let attrs = p.parse_outer_attributes();
|
let attrs = try!(p.parse_outer_attributes());
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
let struct_field_ = ast::StructField_ {
|
let struct_field_ = ast::StructField_ {
|
||||||
kind: UnnamedField(try!(p.parse_visibility())),
|
kind: UnnamedField(try!(p.parse_visibility())),
|
||||||
|
@ -4769,7 +4769,7 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse an element of a struct definition
|
/// Parse an element of a struct definition
|
||||||
fn parse_struct_decl_field(&mut self, allow_pub: bool) -> PResult<StructField> {
|
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 try!(self.eat_keyword(keywords::Pub) ){
|
||||||
if !allow_pub {
|
if !allow_pub {
|
||||||
|
@ -4841,7 +4841,7 @@ impl<'a> Parser<'a> {
|
||||||
let mod_inner_lo = self.span.lo;
|
let mod_inner_lo = self.span.lo;
|
||||||
let old_owns_directory = self.owns_directory;
|
let old_owns_directory = self.owns_directory;
|
||||||
self.owns_directory = true;
|
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));
|
let m = try!(self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo));
|
||||||
self.owns_directory = old_owns_directory;
|
self.owns_directory = old_owns_directory;
|
||||||
self.pop_mod_path();
|
self.pop_mod_path();
|
||||||
|
@ -4990,7 +4990,7 @@ impl<'a> Parser<'a> {
|
||||||
Some(name),
|
Some(name),
|
||||||
id_sp);
|
id_sp);
|
||||||
let mod_inner_lo = p0.span.lo;
|
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));
|
let m0 = try!(p0.parse_mod_items(&token::Eof, mod_inner_lo));
|
||||||
self.sess.included_mod_stack.borrow_mut().pop();
|
self.sess.included_mod_stack.borrow_mut().pop();
|
||||||
Ok((ast::ItemMod(m0), mod_attrs))
|
Ok((ast::ItemMod(m0), mod_attrs))
|
||||||
|
@ -5093,7 +5093,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let abi = opt_abi.unwrap_or(abi::C);
|
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![];
|
let mut foreign_items = vec![];
|
||||||
while let Some(item) = try!(self.parse_foreign_item()) {
|
while let Some(item) = try!(self.parse_foreign_item()) {
|
||||||
|
@ -5143,7 +5143,7 @@ impl<'a> Parser<'a> {
|
||||||
let mut all_nullary = true;
|
let mut all_nullary = true;
|
||||||
let mut any_disr = None;
|
let mut any_disr = None;
|
||||||
while self.token != token::CloseDelim(token::Brace) {
|
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 vlo = self.span.lo;
|
||||||
|
|
||||||
let struct_def;
|
let struct_def;
|
||||||
|
@ -5505,7 +5505,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse a foreign item.
|
/// Parse a foreign item.
|
||||||
fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
|
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 lo = self.span.lo;
|
||||||
let visibility = try!(self.parse_visibility());
|
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>>> {
|
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)
|
self.parse_item_(attrs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5724,7 +5724,7 @@ impl<'a> Parser<'a> {
|
||||||
pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
|
pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
Ok(ast::Crate {
|
Ok(ast::Crate {
|
||||||
attrs: self.parse_inner_attributes(),
|
attrs: try!(self.parse_inner_attributes()),
|
||||||
module: try!(self.parse_mod_items(&token::Eof, lo)),
|
module: try!(self.parse_mod_items(&token::Eof, lo)),
|
||||||
config: self.cfg.clone(),
|
config: self.cfg.clone(),
|
||||||
span: mk_sp(lo, self.span.lo),
|
span: mk_sp(lo, self.span.lo),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue