Skip to content

Commit 7e13fae

Browse files
committed
Auto merge of #27849 - jonas-schievink:macro-errors, r=nikomatsakis
And some small indentation/code style fixes in the macro parser.
2 parents 4c1daeb + 5e8d39e commit 7e13fae

File tree

2 files changed

+51
-47
lines changed

2 files changed

+51
-47
lines changed

src/libsyntax/ext/tt/macro_parser.rs

+50-46
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ pub fn parse(sess: &ParseSess,
401401
}
402402
}
403403
TtToken(sp, SubstNt(..)) => {
404-
return Error(sp, "Cannot transcribe in macro LHS".to_string())
404+
return Error(sp, "missing fragment specifier".to_string())
405405
}
406406
seq @ TtDelimited(..) | seq @ TtToken(_, DocComment(..)) => {
407407
let lower_elts = mem::replace(&mut ei.top_elts, Tt(seq));
@@ -440,20 +440,24 @@ pub fn parse(sess: &ParseSess,
440440
} else {
441441
if (!bb_eis.is_empty() && !next_eis.is_empty())
442442
|| bb_eis.len() > 1 {
443-
let nts = bb_eis.iter().map(|ei| {
444-
match ei.top_elts.get_tt(ei.idx) {
445-
TtToken(_, MatchNt(bind, name, _, _)) => {
443+
let nts = bb_eis.iter().map(|ei| match ei.top_elts.get_tt(ei.idx) {
444+
TtToken(_, MatchNt(bind, name, _, _)) => {
446445
format!("{} ('{}')", name, bind)
447-
}
448-
_ => panic!()
449-
} }).collect::<Vec<String>>().join(" or ");
446+
}
447+
_ => panic!()
448+
}).collect::<Vec<String>>().join(" or ");
449+
450450
return Error(sp, format!(
451-
"local ambiguity: multiple parsing options: \
452-
built-in NTs {} or {} other options.",
453-
nts, next_eis.len()).to_string());
451+
"local ambiguity: multiple parsing options: {}",
452+
match next_eis.len() {
453+
0 => format!("built-in NTs {}.", nts),
454+
1 => format!("built-in NTs {} or 1 other option.", nts),
455+
n => format!("built-in NTs {} or {} other options.", nts, n),
456+
}
457+
))
454458
} else if bb_eis.is_empty() && next_eis.is_empty() {
455459
return Failure(sp, format!("no rules expected the token `{}`",
456-
pprust::token_to_string(&tok)).to_string());
460+
pprust::token_to_string(&tok)));
457461
} else if !next_eis.is_empty() {
458462
/* Now process the next token */
459463
while !next_eis.is_empty() {
@@ -465,14 +469,14 @@ pub fn parse(sess: &ParseSess,
465469

466470
let mut ei = bb_eis.pop().unwrap();
467471
match ei.top_elts.get_tt(ei.idx) {
468-
TtToken(span, MatchNt(_, ident, _, _)) => {
469-
let match_cur = ei.match_cur;
470-
(&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal(
471-
parse_nt(&mut rust_parser, span, &ident.name.as_str()))));
472-
ei.idx += 1;
473-
ei.match_cur += 1;
474-
}
475-
_ => panic!()
472+
TtToken(span, MatchNt(_, ident, _, _)) => {
473+
let match_cur = ei.match_cur;
474+
(&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal(
475+
parse_nt(&mut rust_parser, span, &ident.name.as_str()))));
476+
ei.idx += 1;
477+
ei.match_cur += 1;
478+
}
479+
_ => panic!()
476480
}
477481
cur_eis.push(ei);
478482

@@ -499,37 +503,37 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
499503
// check at the beginning and the parser checks after each bump
500504
panictry!(p.check_unknown_macro_variable());
501505
match name {
502-
"item" => match p.parse_item() {
503-
Some(i) => token::NtItem(i),
504-
None => panic!(p.fatal("expected an item keyword"))
505-
},
506-
"block" => token::NtBlock(panictry!(p.parse_block())),
507-
"stmt" => match p.parse_stmt() {
508-
Some(s) => token::NtStmt(s),
509-
None => panic!(p.fatal("expected a statement"))
510-
},
511-
"pat" => token::NtPat(p.parse_pat()),
512-
"expr" => token::NtExpr(p.parse_expr()),
513-
"ty" => token::NtTy(p.parse_ty()),
514-
// this could be handled like a token, since it is one
515-
"ident" => match p.token {
516-
token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) }
506+
"item" => match p.parse_item() {
507+
Some(i) => token::NtItem(i),
508+
None => panic!(p.fatal("expected an item keyword"))
509+
},
510+
"block" => token::NtBlock(panictry!(p.parse_block())),
511+
"stmt" => match p.parse_stmt() {
512+
Some(s) => token::NtStmt(s),
513+
None => panic!(p.fatal("expected a statement"))
514+
},
515+
"pat" => token::NtPat(p.parse_pat()),
516+
"expr" => token::NtExpr(p.parse_expr()),
517+
"ty" => token::NtTy(p.parse_ty()),
518+
// this could be handled like a token, since it is one
519+
"ident" => match p.token {
520+
token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) }
521+
_ => {
522+
let token_str = pprust::token_to_string(&p.token);
523+
panic!(p.fatal(&format!("expected ident, found {}",
524+
&token_str[..])))
525+
}
526+
},
527+
"path" => {
528+
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
529+
},
530+
"meta" => token::NtMeta(p.parse_meta_item()),
517531
_ => {
518-
let token_str = pprust::token_to_string(&p.token);
519-
panic!(p.fatal(&format!("expected ident, found {}",
520-
&token_str[..])))
521-
}
522-
},
523-
"path" => {
524-
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
525-
}
526-
"meta" => token::NtMeta(p.parse_meta_item()),
527-
_ => {
528-
panic!(p.span_fatal_help(sp,
532+
panic!(p.span_fatal_help(sp,
529533
&format!("invalid fragment specifier `{}`", name),
530534
"valid fragment specifiers are `ident`, `block`, \
531535
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
532536
and `item`"))
533-
}
537+
}
534538
}
535539
}

src/test/compile-fail/macro-match-nonterminal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
macro_rules! test { ($a, $b) => (()); } //~ ERROR Cannot transcribe
11+
macro_rules! test { ($a, $b) => (()); } //~ ERROR missing fragment
1212

1313
fn main() {
1414
test!()

0 commit comments

Comments
 (0)