Auto merge of #30060 - jonas-schievink:asparagus, r=nikomatsakis

Fixes #27092
Fixes #30005
This commit is contained in:
bors 2015-11-25 22:31:10 +00:00
commit 498f08d369
2 changed files with 40 additions and 12 deletions

View File

@ -200,18 +200,19 @@ pub enum NamedMatch {
} }
pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>]) pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
-> HashMap<Name, Rc<NamedMatch>> { -> ParseResult<HashMap<Name, Rc<NamedMatch>>> {
fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>], fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>],
ret_val: &mut HashMap<Name, Rc<NamedMatch>>, idx: &mut usize) { ret_val: &mut HashMap<Name, Rc<NamedMatch>>, idx: &mut usize)
-> Result<(), (codemap::Span, String)> {
match *m { match *m {
TokenTree::Sequence(_, ref seq) => { TokenTree::Sequence(_, ref seq) => {
for next_m in &seq.tts { for next_m in &seq.tts {
n_rec(p_s, next_m, res, ret_val, idx) try!(n_rec(p_s, next_m, res, ret_val, idx))
} }
} }
TokenTree::Delimited(_, ref delim) => { TokenTree::Delimited(_, ref delim) => {
for next_m in &delim.tts { for next_m in &delim.tts {
n_rec(p_s, next_m, res, ret_val, idx) try!(n_rec(p_s, next_m, res, ret_val, idx));
} }
} }
TokenTree::Token(sp, MatchNt(bind_name, _, _, _)) => { TokenTree::Token(sp, MatchNt(bind_name, _, _, _)) => {
@ -221,26 +222,36 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
*idx += 1; *idx += 1;
} }
Occupied(..) => { Occupied(..) => {
panic!(p_s.span_diagnostic return Err((sp, format!("duplicated bind name: {}", bind_name)))
.span_fatal(sp,
&format!("duplicated bind name: {}",
bind_name)))
} }
} }
} }
TokenTree::Token(_, SubstNt(..)) => panic!("Cannot fill in a NT"), TokenTree::Token(sp, SubstNt(..)) => {
return Err((sp, "missing fragment specifier".to_string()))
}
TokenTree::Token(_, _) => (), TokenTree::Token(_, _) => (),
} }
Ok(())
} }
let mut ret_val = HashMap::new(); let mut ret_val = HashMap::new();
let mut idx = 0; let mut idx = 0;
for m in ms { n_rec(p_s, m, res, &mut ret_val, &mut idx) } for m in ms {
ret_val match n_rec(p_s, m, res, &mut ret_val, &mut idx) {
Ok(_) => {},
Err((sp, msg)) => return Error(sp, msg),
}
}
Success(ret_val)
} }
pub enum ParseResult<T> { pub enum ParseResult<T> {
Success(T), Success(T),
/// Arm failed to match
Failure(codemap::Span, String), Failure(codemap::Span, String),
/// Fatal error (malformed macro?). Abort compilation.
Error(codemap::Span, String) Error(codemap::Span, String)
} }
@ -429,7 +440,7 @@ pub fn parse(sess: &ParseSess,
for dv in &mut (&mut eof_eis[0]).matches { for dv in &mut (&mut eof_eis[0]).matches {
v.push(dv.pop().unwrap()); v.push(dv.pop().unwrap());
} }
return Success(nameize(sess, ms, &v[..])); return nameize(sess, ms, &v[..]);
} else if eof_eis.len() > 1 { } else if eof_eis.len() > 1 {
return Error(sp, "ambiguity: multiple successful parses".to_string()); return Error(sp, "ambiguity: multiple successful parses".to_string());
} else { } else {

View File

@ -0,0 +1,17 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
macro_rules! m {
( $( any_token $field_rust_type )* ) => {}; //~ ERROR missing fragment
}
fn main() {
m!();
}