Skip to content

Commit 09c3e82

Browse files
committed
Refactor the second half of parse_tt.
The current structure makes it hard to tell that there are just four distinct code paths, depending on how many items there are in `bb_items` and `next_items`. This commit introduces a `match` that clarifies things.
1 parent 352e621 commit 09c3e82

File tree

1 file changed

+68
-61
lines changed

1 file changed

+68
-61
lines changed

compiler/rustc_expand/src/mbe/macro_parser.rs

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -744,70 +744,77 @@ pub(super) fn parse_tt(
744744
// unnecessary implicit clone later in `Rc::make_mut`.
745745
drop(eof_items);
746746

747-
// If there are no possible next positions AND we aren't waiting for the black-box parser,
748-
// then there is a syntax error.
749-
if bb_items.is_empty() && next_items.is_empty() {
750-
return Failure(parser.token.clone(), "no rules expected this token in macro call");
751-
}
747+
match (next_items.len(), bb_items.len()) {
748+
(0, 0) => {
749+
// There are no possible next positions AND we aren't waiting for the black-box
750+
// parser: syntax error.
751+
return Failure(parser.token.clone(), "no rules expected this token in macro call");
752+
}
752753

753-
if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
754-
// We need to call out to parse some rust nonterminal (black-box) parser. But something
755-
// is wrong, because there is not EXACTLY ONE of these.
756-
let nts = bb_items
757-
.iter()
758-
.map(|item| match item.top_elts.get_tt(item.idx) {
759-
TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
760-
_ => panic!(),
761-
})
762-
.collect::<Vec<String>>()
763-
.join(" or ");
764-
765-
return Error(
766-
parser.token.span,
767-
format!(
768-
"local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}",
769-
match next_items.len() {
770-
0 => format!("built-in NTs {}.", nts),
771-
1 => format!("built-in NTs {} or 1 other option.", nts),
772-
n => format!("built-in NTs {} or {} other options.", nts, n),
773-
}
774-
),
775-
);
776-
}
754+
(_, 0) => {
755+
// Dump all possible `next_items` into `cur_items` for the next iteration. Then
756+
// process the next token.
757+
cur_items.extend(next_items.drain(..));
758+
parser.to_mut().bump();
759+
}
777760

778-
if !next_items.is_empty() {
779-
// Dump all possible `next_items` into `cur_items` for the next iteration. Then process
780-
// the next token.
781-
cur_items.extend(next_items.drain(..));
782-
parser.to_mut().bump();
783-
} else {
784-
// Finally, we have the case where we need to call the black-box parser to get some
785-
// nonterminal.
786-
assert_eq!(bb_items.len(), 1);
787-
788-
let mut item = bb_items.pop().unwrap();
789-
if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
790-
let match_cur = item.match_cur;
791-
// We use the span of the metavariable declaration to determine any
792-
// edition-specific matching behavior for non-terminals.
793-
let nt = match parser.to_mut().parse_nonterminal(kind) {
794-
Err(mut err) => {
795-
err.span_label(
796-
span,
797-
format!("while parsing argument for this `{}` macro fragment", kind),
798-
)
799-
.emit();
800-
return ErrorReported;
801-
}
802-
Ok(nt) => nt,
803-
};
804-
item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
805-
item.idx += 1;
806-
item.match_cur += 1;
807-
} else {
808-
unreachable!()
761+
(0, 1) => {
762+
// We need to call the black-box parser to get some nonterminal.
763+
let mut item = bb_items.pop().unwrap();
764+
if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx)
765+
{
766+
let match_cur = item.match_cur;
767+
// We use the span of the metavariable declaration to determine any
768+
// edition-specific matching behavior for non-terminals.
769+
let nt = match parser.to_mut().parse_nonterminal(kind) {
770+
Err(mut err) => {
771+
err.span_label(
772+
span,
773+
format!(
774+
"while parsing argument for this `{}` macro fragment",
775+
kind
776+
),
777+
)
778+
.emit();
779+
return ErrorReported;
780+
}
781+
Ok(nt) => nt,
782+
};
783+
item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
784+
item.idx += 1;
785+
item.match_cur += 1;
786+
} else {
787+
unreachable!()
788+
}
789+
cur_items.push(item);
790+
}
791+
792+
(_, _) => {
793+
// We need to call the black-box parser to get some nonterminal, but something is
794+
// wrong.
795+
let nts = bb_items
796+
.iter()
797+
.map(|item| match item.top_elts.get_tt(item.idx) {
798+
TokenTree::MetaVarDecl(_, bind, Some(kind)) => {
799+
format!("{} ('{}')", kind, bind)
800+
}
801+
_ => panic!(),
802+
})
803+
.collect::<Vec<String>>()
804+
.join(" or ");
805+
806+
return Error(
807+
parser.token.span,
808+
format!(
809+
"local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}",
810+
match next_items.len() {
811+
0 => format!("built-in NTs {}.", nts),
812+
1 => format!("built-in NTs {} or 1 other option.", nts),
813+
n => format!("built-in NTs {} or {} other options.", nts, n),
814+
}
815+
),
816+
);
809817
}
810-
cur_items.push(item);
811818
}
812819

813820
assert!(!cur_items.is_empty());

0 commit comments

Comments
 (0)