Skip to content

Commit 498f08d

Browse files
committed
Auto merge of #30060 - jonas-schievink:asparagus, r=nikomatsakis
Fixes #27092 Fixes #30005
2 parents bef2af6 + 47cb5d8 commit 498f08d

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

src/libsyntax/ext/tt/macro_parser.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,19 @@ pub enum NamedMatch {
200200
}
201201

202202
pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
203-
-> HashMap<Name, Rc<NamedMatch>> {
203+
-> ParseResult<HashMap<Name, Rc<NamedMatch>>> {
204204
fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>],
205-
ret_val: &mut HashMap<Name, Rc<NamedMatch>>, idx: &mut usize) {
205+
ret_val: &mut HashMap<Name, Rc<NamedMatch>>, idx: &mut usize)
206+
-> Result<(), (codemap::Span, String)> {
206207
match *m {
207208
TokenTree::Sequence(_, ref seq) => {
208209
for next_m in &seq.tts {
209-
n_rec(p_s, next_m, res, ret_val, idx)
210+
try!(n_rec(p_s, next_m, res, ret_val, idx))
210211
}
211212
}
212213
TokenTree::Delimited(_, ref delim) => {
213214
for next_m in &delim.tts {
214-
n_rec(p_s, next_m, res, ret_val, idx)
215+
try!(n_rec(p_s, next_m, res, ret_val, idx));
215216
}
216217
}
217218
TokenTree::Token(sp, MatchNt(bind_name, _, _, _)) => {
@@ -221,26 +222,36 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
221222
*idx += 1;
222223
}
223224
Occupied(..) => {
224-
panic!(p_s.span_diagnostic
225-
.span_fatal(sp,
226-
&format!("duplicated bind name: {}",
227-
bind_name)))
225+
return Err((sp, format!("duplicated bind name: {}", bind_name)))
228226
}
229227
}
230228
}
231-
TokenTree::Token(_, SubstNt(..)) => panic!("Cannot fill in a NT"),
229+
TokenTree::Token(sp, SubstNt(..)) => {
230+
return Err((sp, "missing fragment specifier".to_string()))
231+
}
232232
TokenTree::Token(_, _) => (),
233233
}
234+
235+
Ok(())
234236
}
237+
235238
let mut ret_val = HashMap::new();
236239
let mut idx = 0;
237-
for m in ms { n_rec(p_s, m, res, &mut ret_val, &mut idx) }
238-
ret_val
240+
for m in ms {
241+
match n_rec(p_s, m, res, &mut ret_val, &mut idx) {
242+
Ok(_) => {},
243+
Err((sp, msg)) => return Error(sp, msg),
244+
}
245+
}
246+
247+
Success(ret_val)
239248
}
240249

241250
pub enum ParseResult<T> {
242251
Success(T),
252+
/// Arm failed to match
243253
Failure(codemap::Span, String),
254+
/// Fatal error (malformed macro?). Abort compilation.
244255
Error(codemap::Span, String)
245256
}
246257

@@ -429,7 +440,7 @@ pub fn parse(sess: &ParseSess,
429440
for dv in &mut (&mut eof_eis[0]).matches {
430441
v.push(dv.pop().unwrap());
431442
}
432-
return Success(nameize(sess, ms, &v[..]));
443+
return nameize(sess, ms, &v[..]);
433444
} else if eof_eis.len() > 1 {
434445
return Error(sp, "ambiguity: multiple successful parses".to_string());
435446
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! m {
12+
( $( any_token $field_rust_type )* ) => {}; //~ ERROR missing fragment
13+
}
14+
15+
fn main() {
16+
m!();
17+
}

0 commit comments

Comments
 (0)