Skip to content

Commit d74bf2b

Browse files
committed
macros: Unnest nested matches with let-else and let chains
Non-functional change to simplify control flow.
1 parent 27eb269 commit d74bf2b

File tree

1 file changed

+63
-58
lines changed

1 file changed

+63
-58
lines changed

compiler/rustc_expand/src/mbe/quoted.rs

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -54,66 +54,71 @@ pub(super) fn parse(
5454
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
5555
// parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
5656
let tree = parse_tree(tree, &mut iter, parsing_patterns, sess, node_id, features, edition);
57-
match tree {
58-
TokenTree::MetaVar(start_sp, ident) if parsing_patterns => {
59-
// Not consuming the next token immediately, as it may not be a colon
60-
let span = match iter.peek() {
61-
Some(&tokenstream::TokenTree::Token(
62-
Token { kind: token::Colon, span: colon_span },
63-
_,
64-
)) => {
65-
// Consume the colon first
66-
iter.next();
67-
68-
// It's ok to consume the next tree no matter how,
69-
// since if it's not a token then it will be an invalid declaration.
70-
match iter.next() {
71-
Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
72-
Some((fragment, _)) => {
73-
let span = token.span.with_lo(start_sp.lo());
74-
let edition = || {
75-
// FIXME(#85708) - once we properly decode a foreign
76-
// crate's `SyntaxContext::root`, then we can replace
77-
// this with just `span.edition()`. A
78-
// `SyntaxContext::root()` from the current crate will
79-
// have the edition of the current crate, and a
80-
// `SyntaxContext::root()` from a foreign crate will
81-
// have the edition of that crate (which we manually
82-
// retrieve via the `edition` parameter).
83-
if !span.from_expansion() {
84-
edition
85-
} else {
86-
span.edition()
87-
}
88-
};
89-
let kind = NonterminalKind::from_symbol(fragment.name, edition)
90-
.unwrap_or_else(|| {
91-
sess.dcx().emit_err(errors::InvalidFragmentSpecifier {
92-
span,
93-
fragment,
94-
help: VALID_FRAGMENT_NAMES_MSG.into(),
95-
});
96-
NonterminalKind::Ident
97-
});
98-
result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
99-
continue;
100-
}
101-
_ => token.span,
102-
},
103-
// Invalid, return a nice source location
104-
_ => colon_span.with_lo(start_sp.lo()),
105-
}
106-
}
107-
// Whether it's none or some other tree, it doesn't belong to
108-
// the current meta variable, returning the original span.
109-
_ => start_sp,
110-
};
11157

112-
result.push(TokenTree::MetaVarDecl(span, ident, None));
113-
}
58+
if !parsing_patterns {
59+
// No matchers allowed, nothing to process here
60+
result.push(tree);
61+
continue;
62+
}
63+
64+
let TokenTree::MetaVar(start_sp, ident) = tree else {
65+
// Not a metavariable, just return the tree
66+
result.push(tree);
67+
continue;
68+
};
11469

115-
// Not a metavar or no matchers allowed, so just return the tree
116-
_ => result.push(tree),
70+
// Push a metavariable with no fragment specifier at the given span
71+
let mut push_empty_metavar = |span| {
72+
result.push(TokenTree::MetaVarDecl(span, ident, None));
73+
};
74+
75+
// Not consuming the next token immediately, as it may not be a colon
76+
if let Some(peek) = iter.peek()
77+
&& let tokenstream::TokenTree::Token(token, _spacing) = peek
78+
&& let Token { kind: token::Colon, span: colon_span } = token
79+
{
80+
// Next token is a colon; consume it
81+
iter.next();
82+
83+
// It's ok to consume the next tree no matter how,
84+
// since if it's not a token then it will be an invalid declaration.
85+
let Some(tokenstream::TokenTree::Token(token, _)) = iter.next() else {
86+
// Invalid, return a nice source location as `var:`
87+
push_empty_metavar(colon_span.with_lo(start_sp.lo()));
88+
continue;
89+
};
90+
91+
let Some((fragment, _)) = token.ident() else {
92+
// No identifier for the fragment specifier;
93+
push_empty_metavar(token.span);
94+
continue;
95+
};
96+
97+
let span = token.span.with_lo(start_sp.lo());
98+
let edition = || {
99+
// FIXME(#85708) - once we properly decode a foreign
100+
// crate's `SyntaxContext::root`, then we can replace
101+
// this with just `span.edition()`. A
102+
// `SyntaxContext::root()` from the current crate will
103+
// have the edition of the current crate, and a
104+
// `SyntaxContext::root()` from a foreign crate will
105+
// have the edition of that crate (which we manually
106+
// retrieve via the `edition` parameter).
107+
if !span.from_expansion() { edition } else { span.edition() }
108+
};
109+
let kind = NonterminalKind::from_symbol(fragment.name, edition).unwrap_or_else(|| {
110+
sess.dcx().emit_err(errors::InvalidFragmentSpecifier {
111+
span,
112+
fragment,
113+
help: VALID_FRAGMENT_NAMES_MSG.into(),
114+
});
115+
NonterminalKind::Ident
116+
});
117+
result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
118+
} else {
119+
// Whether it's none or some other tree, it doesn't belong to
120+
// the current meta variable, returning the original span.
121+
push_empty_metavar(start_sp);
117122
}
118123
}
119124
result

0 commit comments

Comments
 (0)