Skip to content

Commit de95857

Browse files
committed
Don't panic for fatal errors in attribute parsing.
1 parent c141f47 commit de95857

File tree

5 files changed

+56
-54
lines changed

5 files changed

+56
-54
lines changed

src/libsyntax/ext/cfg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
2626
tts: &[ast::TokenTree])
2727
-> Box<base::MacResult+'static> {
2828
let mut p = cx.new_parser_from_tts(tts);
29-
let cfg = p.parse_meta_item();
29+
let cfg = panictry!(p.parse_meta_item());
3030

3131
if !panictry!(p.eat(&token::Eof)){
3232
cx.span_err(sp, "expected 1 cfg-pattern");

src/libsyntax/ext/tt/macro_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
526526
"path" => {
527527
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
528528
},
529-
"meta" => token::NtMeta(p.parse_meta_item()),
529+
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
530530
_ => {
531531
panic!(p.span_fatal_help(sp,
532532
&format!("invalid fragment specifier `{}`", name),

src/libsyntax/parse/attr.rs

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,21 @@ use attr;
1212
use ast;
1313
use codemap::{spanned, Spanned, mk_sp, Span};
1414
use parse::common::*; //resolve bug?
15+
use parse::PResult;
1516
use parse::token;
1617
use parse::parser::{Parser, TokenType};
1718
use ptr::P;
1819

1920
impl<'a> Parser<'a> {
2021
/// Parse attributes that appear before an item
21-
pub fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
22+
pub fn parse_outer_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
2223
let mut attrs: Vec<ast::Attribute> = Vec::new();
2324
loop {
2425
debug!("parse_outer_attributes: self.token={:?}",
2526
self.token);
2627
match self.token {
2728
token::Pound => {
28-
attrs.push(self.parse_attribute(false));
29+
attrs.push(try!(self.parse_attribute(false)));
2930
}
3031
token::DocComment(s) => {
3132
let attr = ::attr::mk_sugared_doc_attr(
@@ -35,32 +36,32 @@ impl<'a> Parser<'a> {
3536
self.span.hi
3637
);
3738
if attr.node.style != ast::AttrStyle::Outer {
38-
panic!(self.fatal("expected outer comment"));
39+
return Err(self.fatal("expected outer comment"));
3940
}
4041
attrs.push(attr);
41-
panictry!(self.bump());
42+
try!(self.bump());
4243
}
4344
_ => break
4445
}
4546
}
46-
return attrs;
47+
return Ok(attrs);
4748
}
4849

4950
/// Matches `attribute = # ! [ meta_item ]`
5051
///
5152
/// If permit_inner is true, then a leading `!` indicates an inner
5253
/// attribute
53-
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
54+
fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute> {
5455
debug!("parse_attributes: permit_inner={:?} self.token={:?}",
5556
permit_inner, self.token);
5657
let (span, value, mut style) = match self.token {
5758
token::Pound => {
5859
let lo = self.span.lo;
59-
panictry!(self.bump());
60+
try!(self.bump());
6061

6162
if permit_inner { self.expected_tokens.push(TokenType::Token(token::Not)); }
6263
let style = if self.token == token::Not {
63-
panictry!(self.bump());
64+
try!(self.bump());
6465
if !permit_inner {
6566
let span = self.span;
6667
self.span_err(span,
@@ -74,43 +75,43 @@ impl<'a> Parser<'a> {
7475
ast::AttrStyle::Outer
7576
};
7677

77-
panictry!(self.expect(&token::OpenDelim(token::Bracket)));
78-
let meta_item = self.parse_meta_item();
78+
try!(self.expect(&token::OpenDelim(token::Bracket)));
79+
let meta_item = try!(self.parse_meta_item());
7980
let hi = self.span.hi;
80-
panictry!(self.expect(&token::CloseDelim(token::Bracket)));
81+
try!(self.expect(&token::CloseDelim(token::Bracket)));
8182

8283
(mk_sp(lo, hi), meta_item, style)
8384
}
8485
_ => {
8586
let token_str = self.this_token_to_string();
86-
panic!(self.fatal(&format!("expected `#`, found `{}`", token_str)));
87+
return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
8788
}
8889
};
8990

9091
if permit_inner && self.token == token::Semi {
91-
panictry!(self.bump());
92+
try!(self.bump());
9293
self.span_warn(span, "this inner attribute syntax is deprecated. \
9394
The new syntax is `#![foo]`, with a bang and no semicolon");
9495
style = ast::AttrStyle::Inner;
9596
}
9697

97-
return Spanned {
98+
Ok(Spanned {
9899
span: span,
99100
node: ast::Attribute_ {
100101
id: attr::mk_attr_id(),
101102
style: style,
102103
value: value,
103104
is_sugared_doc: false
104105
}
105-
};
106+
})
106107
}
107108

108109
/// Parse attributes that appear after the opening of an item. These should
109110
/// be preceded by an exclamation mark, but we accept and warn about one
110111
/// terminated by a semicolon.
111112
112113
/// matches inner_attrs*
113-
pub fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
114+
pub fn parse_inner_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
114115
let mut attrs: Vec<ast::Attribute> = vec![];
115116
loop {
116117
match self.token {
@@ -120,7 +121,7 @@ impl<'a> Parser<'a> {
120121
break;
121122
}
122123

123-
let attr = self.parse_attribute(true);
124+
let attr = try!(self.parse_attribute(true));
124125
assert!(attr.node.style == ast::AttrStyle::Inner);
125126
attrs.push(attr);
126127
}
@@ -131,21 +132,21 @@ impl<'a> Parser<'a> {
131132
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), str, lo, hi);
132133
if attr.node.style == ast::AttrStyle::Inner {
133134
attrs.push(attr);
134-
panictry!(self.bump());
135+
try!(self.bump());
135136
} else {
136137
break;
137138
}
138139
}
139140
_ => break
140141
}
141142
}
142-
attrs
143+
Ok(attrs)
143144
}
144145

145146
/// matches meta_item = IDENT
146147
/// | IDENT = lit
147148
/// | IDENT meta_seq
148-
pub fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
149+
pub fn parse_meta_item(&mut self) -> PResult<P<ast::MetaItem>> {
149150
let nt_meta = match self.token {
150151
token::Interpolated(token::NtMeta(ref e)) => {
151152
Some(e.clone())
@@ -155,19 +156,19 @@ impl<'a> Parser<'a> {
155156

156157
match nt_meta {
157158
Some(meta) => {
158-
panictry!(self.bump());
159-
return meta;
159+
try!(self.bump());
160+
return Ok(meta);
160161
}
161162
None => {}
162163
}
163164

164165
let lo = self.span.lo;
165-
let ident = panictry!(self.parse_ident());
166+
let ident = try!(self.parse_ident());
166167
let name = self.id_to_interned_str(ident);
167168
match self.token {
168169
token::Eq => {
169-
panictry!(self.bump());
170-
let lit = panictry!(self.parse_lit());
170+
try!(self.bump());
171+
let lit = try!(self.parse_lit());
171172
// FIXME #623 Non-string meta items are not serialized correctly;
172173
// just forbid them for now
173174
match lit.node {
@@ -179,25 +180,25 @@ impl<'a> Parser<'a> {
179180
}
180181
}
181182
let hi = self.span.hi;
182-
P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
183+
Ok(P(spanned(lo, hi, ast::MetaNameValue(name, lit))))
183184
}
184185
token::OpenDelim(token::Paren) => {
185-
let inner_items = self.parse_meta_seq();
186+
let inner_items = try!(self.parse_meta_seq());
186187
let hi = self.span.hi;
187-
P(spanned(lo, hi, ast::MetaList(name, inner_items)))
188+
Ok(P(spanned(lo, hi, ast::MetaList(name, inner_items))))
188189
}
189190
_ => {
190191
let hi = self.last_span.hi;
191-
P(spanned(lo, hi, ast::MetaWord(name)))
192+
Ok(P(spanned(lo, hi, ast::MetaWord(name))))
192193
}
193194
}
194195
}
195196

196197
/// matches meta_seq = ( COMMASEP(meta_item) )
197-
fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
198-
panictry!(self.parse_seq(&token::OpenDelim(token::Paren),
199-
&token::CloseDelim(token::Paren),
200-
seq_sep_trailing_allowed(token::Comma),
201-
|p| Ok(p.parse_meta_item()))).node
198+
fn parse_meta_seq(&mut self) -> PResult<Vec<P<ast::MetaItem>>> {
199+
self.parse_unspanned_seq(&token::OpenDelim(token::Paren),
200+
&token::CloseDelim(token::Paren),
201+
seq_sep_trailing_allowed(token::Comma),
202+
|p| p.parse_meta_item())
202203
}
203204
}

src/libsyntax/parse/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ pub fn parse_crate_attrs_from_file(
8282
cfg: ast::CrateConfig,
8383
sess: &ParseSess
8484
) -> Vec<ast::Attribute> {
85-
new_parser_from_file(sess, cfg, input).parse_inner_attributes()
85+
// FIXME: maybe_aborted?
86+
panictry!(new_parser_from_file(sess, cfg, input).parse_inner_attributes())
8687
}
8788

8889
pub fn parse_crate_from_source_str(name: String,
@@ -106,7 +107,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
106107
cfg,
107108
name,
108109
source);
109-
maybe_aborted(p.parse_inner_attributes(), p)
110+
maybe_aborted(panictry!(p.parse_inner_attributes()), p)
110111
}
111112

112113
pub fn parse_expr_from_source_str(name: String,
@@ -133,7 +134,7 @@ pub fn parse_meta_from_source_str(name: String,
133134
sess: &ParseSess)
134135
-> P<ast::MetaItem> {
135136
let mut p = new_parser_from_source_str(sess, cfg, name, source);
136-
maybe_aborted(p.parse_meta_item(), p)
137+
maybe_aborted(panictry!(p.parse_meta_item()), p)
137138
}
138139

139140
pub fn parse_stmt_from_source_str(name: String,

src/libsyntax/parse/parser.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ impl<'a> Parser<'a> {
11741174
seq_sep_none(),
11751175
|p| -> PResult<P<TraitItem>> {
11761176
maybe_whole!(no_clone p, NtTraitItem);
1177-
let mut attrs = p.parse_outer_attributes();
1177+
let mut attrs = try!(p.parse_outer_attributes());
11781178
let lo = p.span.lo;
11791179

11801180
let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
@@ -2956,7 +2956,7 @@ impl<'a> Parser<'a> {
29562956
pub fn parse_arm_nopanic(&mut self) -> PResult<Arm> {
29572957
maybe_whole!(no_clone self, NtArm);
29582958

2959-
let attrs = self.parse_outer_attributes();
2959+
let attrs = try!(self.parse_outer_attributes());
29602960
let pats = try!(self.parse_pats());
29612961
let mut guard = None;
29622962
if try!(self.eat_keyword(keywords::If) ){
@@ -3465,7 +3465,7 @@ impl<'a> Parser<'a> {
34653465
}
34663466
}
34673467

3468-
let attrs = self.parse_outer_attributes();
3468+
let attrs = try!(self.parse_outer_attributes());
34693469
let lo = self.span.lo;
34703470

34713471
Ok(Some(if self.check_keyword(keywords::Let) {
@@ -3607,7 +3607,7 @@ impl<'a> Parser<'a> {
36073607

36083608
let lo = self.span.lo;
36093609
try!(self.expect(&token::OpenDelim(token::Brace)));
3610-
Ok((self.parse_inner_attributes(),
3610+
Ok((try!(self.parse_inner_attributes()),
36113611
try!(self.parse_block_tail(lo, DefaultBlock))))
36123612
}
36133613

@@ -4431,7 +4431,7 @@ impl<'a> Parser<'a> {
44314431
pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
44324432
maybe_whole!(no_clone self, NtImplItem);
44334433

4434-
let mut attrs = self.parse_outer_attributes();
4434+
let mut attrs = try!(self.parse_outer_attributes());
44354435
let lo = self.span.lo;
44364436
let vis = try!(self.parse_visibility());
44374437
let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
@@ -4608,7 +4608,7 @@ impl<'a> Parser<'a> {
46084608
generics.where_clause = try!(self.parse_where_clause());
46094609

46104610
try!(self.expect(&token::OpenDelim(token::Brace)));
4611-
let attrs = self.parse_inner_attributes();
4611+
let attrs = try!(self.parse_inner_attributes());
46124612

46134613
let mut impl_items = vec![];
46144614
while !try!(self.eat(&token::CloseDelim(token::Brace))) {
@@ -4727,7 +4727,7 @@ impl<'a> Parser<'a> {
47274727
&token::CloseDelim(token::Paren),
47284728
seq_sep_trailing_allowed(token::Comma),
47294729
|p| {
4730-
let attrs = p.parse_outer_attributes();
4730+
let attrs = try!(p.parse_outer_attributes());
47314731
let lo = p.span.lo;
47324732
let struct_field_ = ast::StructField_ {
47334733
kind: UnnamedField(try!(p.parse_visibility())),
@@ -4769,7 +4769,7 @@ impl<'a> Parser<'a> {
47694769
/// Parse an element of a struct definition
47704770
fn parse_struct_decl_field(&mut self, allow_pub: bool) -> PResult<StructField> {
47714771

4772-
let attrs = self.parse_outer_attributes();
4772+
let attrs = try!(self.parse_outer_attributes());
47734773

47744774
if try!(self.eat_keyword(keywords::Pub) ){
47754775
if !allow_pub {
@@ -4841,7 +4841,7 @@ impl<'a> Parser<'a> {
48414841
let mod_inner_lo = self.span.lo;
48424842
let old_owns_directory = self.owns_directory;
48434843
self.owns_directory = true;
4844-
let attrs = self.parse_inner_attributes();
4844+
let attrs = try!(self.parse_inner_attributes());
48454845
let m = try!(self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo));
48464846
self.owns_directory = old_owns_directory;
48474847
self.pop_mod_path();
@@ -4990,7 +4990,7 @@ impl<'a> Parser<'a> {
49904990
Some(name),
49914991
id_sp);
49924992
let mod_inner_lo = p0.span.lo;
4993-
let mod_attrs = p0.parse_inner_attributes();
4993+
let mod_attrs = try!(p0.parse_inner_attributes());
49944994
let m0 = try!(p0.parse_mod_items(&token::Eof, mod_inner_lo));
49954995
self.sess.included_mod_stack.borrow_mut().pop();
49964996
Ok((ast::ItemMod(m0), mod_attrs))
@@ -5093,7 +5093,7 @@ impl<'a> Parser<'a> {
50935093

50945094
let abi = opt_abi.unwrap_or(abi::C);
50955095

5096-
attrs.extend(self.parse_inner_attributes());
5096+
attrs.extend(try!(self.parse_inner_attributes()));
50975097

50985098
let mut foreign_items = vec![];
50995099
while let Some(item) = try!(self.parse_foreign_item()) {
@@ -5143,7 +5143,7 @@ impl<'a> Parser<'a> {
51435143
let mut all_nullary = true;
51445144
let mut any_disr = None;
51455145
while self.token != token::CloseDelim(token::Brace) {
5146-
let variant_attrs = self.parse_outer_attributes();
5146+
let variant_attrs = try!(self.parse_outer_attributes());
51475147
let vlo = self.span.lo;
51485148

51495149
let struct_def;
@@ -5505,7 +5505,7 @@ impl<'a> Parser<'a> {
55055505

55065506
/// Parse a foreign item.
55075507
fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
5508-
let attrs = self.parse_outer_attributes();
5508+
let attrs = try!(self.parse_outer_attributes());
55095509
let lo = self.span.lo;
55105510
let visibility = try!(self.parse_visibility());
55115511

@@ -5605,7 +5605,7 @@ impl<'a> Parser<'a> {
56055605
}
56065606

56075607
pub fn parse_item_nopanic(&mut self) -> PResult<Option<P<Item>>> {
5608-
let attrs = self.parse_outer_attributes();
5608+
let attrs = try!(self.parse_outer_attributes());
56095609
self.parse_item_(attrs, true)
56105610
}
56115611

@@ -5724,7 +5724,7 @@ impl<'a> Parser<'a> {
57245724
pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
57255725
let lo = self.span.lo;
57265726
Ok(ast::Crate {
5727-
attrs: self.parse_inner_attributes(),
5727+
attrs: try!(self.parse_inner_attributes()),
57285728
module: try!(self.parse_mod_items(&token::Eof, lo)),
57295729
config: self.cfg.clone(),
57305730
span: mk_sp(lo, self.span.lo),

0 commit comments

Comments
 (0)