1
Fork 0

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:
Nicholas Nethercote 2022-11-18 11:24:21 +11:00
parent 1cbc45942d
commit 3e3a4192d8
33 changed files with 252 additions and 248 deletions

View file

@ -11,10 +11,9 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser;
use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, Mutability, PatKind};
use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_span::edition::Edition;
@ -466,26 +465,26 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
self.ibox(0);
match &item.args {
MacArgs::Delimited(_, delim, tokens) => self.print_mac_common(
AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common(
Some(MacHeader::Path(&item.path)),
false,
None,
Some(delim.to_token()),
delim.to_token(),
tokens,
true,
span,
),
MacArgs::Empty => {
AttrArgs::Empty => {
self.print_path(&item.path, false, 0);
}
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
self.print_path(&item.path, false, 0);
self.space();
self.word_space("=");
let token_str = self.expr_to_string(expr);
self.word(token_str);
}
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
self.print_path(&item.path, false, 0);
self.space();
self.word_space("=");
@ -544,7 +543,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
None,
false,
None,
Some(*delim),
*delim,
tts,
convert_dollar_crate,
dspan.entire(),
@ -570,12 +569,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
header: Option<MacHeader<'_>>,
has_bang: bool,
ident: Option<Ident>,
delim: Option<Delimiter>,
delim: Delimiter,
tts: &TokenStream,
convert_dollar_crate: bool,
span: Span,
) {
if delim == Some(Delimiter::Brace) {
if delim == Delimiter::Brace {
self.cbox(INDENT_UNIT);
}
match header {
@ -591,7 +590,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
self.print_ident(ident);
}
match delim {
Some(Delimiter::Brace) => {
Delimiter::Brace => {
if header.is_some() || has_bang || ident.is_some() {
self.nbsp();
}
@ -605,7 +604,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
let empty = tts.is_empty();
self.bclose(span, empty);
}
Some(delim) => {
delim => {
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
self.word(token_str);
self.ibox(0);
@ -614,11 +613,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
self.word(token_str);
}
None => {
self.ibox(0);
self.print_tts(tts, convert_dollar_crate);
self.end();
}
}
}
@ -639,8 +633,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
Some(MacHeader::Keyword(kw)),
has_bang,
Some(*ident),
macro_def.body.delim(),
&macro_def.body.inner_tokens(),
macro_def.body.delim.to_token(),
&macro_def.body.tokens.clone(),
true,
sp,
);
@ -1230,8 +1224,8 @@ impl<'a> State<'a> {
Some(MacHeader::Path(&m.path)),
true,
None,
m.args.delim(),
&m.args.inner_tokens(),
m.args.delim.to_token(),
&m.args.tokens.clone(),
true,
m.span(),
);