Auto merge of #30060 - jonas-schievink:asparagus, r=nikomatsakis
Fixes #27092 Fixes #30005
This commit is contained in:
commit
498f08d369
@ -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 {
|
||||||
|
17
src/test/compile-fail/macro-missing-fragment.rs
Normal file
17
src/test/compile-fail/macro-missing-fragment.rs
Normal 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!();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user