Split MacArgs
in two.
`MacArgs` is an enum with three variants: `Empty`, `Delimited`, and `Eq`. It's used in two ways: - For representing attribute macro arguments (e.g. in `AttrItem`), where all three variants are used. - For representing function-like macros (e.g. in `MacCall` and `MacroDef`), where only the `Delimited` variant is used. In other words, `MacArgs` is used in two quite different places due to them having partial overlap. I find this makes the code hard to read. It also leads to various unreachable code paths, and allows invalid values (such as accidentally using `MacArgs::Empty` in a `MacCall`). This commit splits `MacArgs` in two: - `DelimArgs` is a new struct just for the "delimited arguments" case. It is now used in `MacCall` and `MacroDef`. - `AttrArgs` is a renaming of the old `MacArgs` enum for the attribute macro case. Its `Delimited` variant now contains a `DelimArgs`. Various other related things are renamed as well. These changes make the code clearer, avoids several unreachable paths, and disallows the invalid values.
This commit is contained in:
parent
1cbc45942d
commit
3e3a4192d8
33 changed files with 252 additions and 248 deletions
|
@ -25,8 +25,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
|
|||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::AttrId;
|
||||
use rustc_ast::DUMMY_NODE_ID;
|
||||
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, Extern};
|
||||
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacArgsEq, MacDelimiter, Mutability, StrLit};
|
||||
use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, DelimArgs, Extern};
|
||||
use rustc_ast::{Async, AttrArgs, AttrArgsEq, Expr, ExprKind, MacDelimiter, Mutability, StrLit};
|
||||
use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -1249,39 +1249,40 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_mac_args(&mut self) -> PResult<'a, P<MacArgs>> {
|
||||
self.parse_mac_args_common(true).map(P)
|
||||
fn parse_delim_args(&mut self) -> PResult<'a, P<DelimArgs>> {
|
||||
if let Some(args) = self.parse_delim_args_inner() { Ok(P(args)) } else { self.unexpected() }
|
||||
}
|
||||
|
||||
fn parse_attr_args(&mut self) -> PResult<'a, MacArgs> {
|
||||
self.parse_mac_args_common(false)
|
||||
}
|
||||
|
||||
fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, MacArgs> {
|
||||
Ok(
|
||||
if self.check(&token::OpenDelim(Delimiter::Parenthesis))
|
||||
|| self.check(&token::OpenDelim(Delimiter::Bracket))
|
||||
|| self.check(&token::OpenDelim(Delimiter::Brace))
|
||||
{
|
||||
match self.parse_token_tree() {
|
||||
TokenTree::Delimited(dspan, delim, tokens) =>
|
||||
// We've confirmed above that there is a delimiter so unwrapping is OK.
|
||||
{
|
||||
MacArgs::Delimited(dspan, MacDelimiter::from_token(delim).unwrap(), tokens)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else if !delimited_only {
|
||||
if self.eat(&token::Eq) {
|
||||
let eq_span = self.prev_token.span;
|
||||
MacArgs::Eq(eq_span, MacArgsEq::Ast(self.parse_expr_force_collect()?))
|
||||
} else {
|
||||
MacArgs::Empty
|
||||
}
|
||||
fn parse_attr_args(&mut self) -> PResult<'a, AttrArgs> {
|
||||
Ok(if let Some(args) = self.parse_delim_args_inner() {
|
||||
AttrArgs::Delimited(args)
|
||||
} else {
|
||||
if self.eat(&token::Eq) {
|
||||
let eq_span = self.prev_token.span;
|
||||
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?))
|
||||
} else {
|
||||
return self.unexpected();
|
||||
},
|
||||
)
|
||||
AttrArgs::Empty
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> {
|
||||
if self.check(&token::OpenDelim(Delimiter::Parenthesis))
|
||||
|| self.check(&token::OpenDelim(Delimiter::Bracket))
|
||||
|| self.check(&token::OpenDelim(Delimiter::Brace))
|
||||
{
|
||||
match self.parse_token_tree() {
|
||||
// We've confirmed above that there is a delimiter so unwrapping is OK.
|
||||
TokenTree::Delimited(dspan, delim, tokens) => Some(DelimArgs {
|
||||
dspan,
|
||||
delim: MacDelimiter::from_token(delim).unwrap(),
|
||||
tokens,
|
||||
}),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_or_use_outer_attributes(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue