diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-11-18 11:24:21 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-11-22 09:04:15 +1100 |
| commit | 3e3a4192d8cda0c308ea87b2e8f6f1e8dcc74739 (patch) | |
| tree | 5cbe2cba5da6a3eabde9d310eb7c0ac5aaa1d83c | |
| parent | 1cbc45942d5c0f6eb5d94e3b10762ba541958035 (diff) | |
| download | rust-3e3a4192d8cda0c308ea87b2e8f6f1e8dcc74739.tar.gz rust-3e3a4192d8cda0c308ea87b2e8f6f1e8dcc74739.zip | |
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.
33 files changed, 251 insertions, 247 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4ad9981991d..fa745a8e08b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1544,55 +1544,48 @@ pub enum ClosureBinder { #[derive(Clone, Encodable, Decodable, Debug)] pub struct MacCall { pub path: Path, - pub args: P<MacArgs>, + pub args: P<DelimArgs>, pub prior_type_ascription: Option<(Span, bool)>, } impl MacCall { pub fn span(&self) -> Span { - self.path.span.to(self.args.span().unwrap_or(self.path.span)) + self.path.span.to(self.args.dspan.entire()) } } -/// Arguments passed to an attribute or a function-like macro. +/// Arguments passed to an attribute macro. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgs { - /// No arguments - `#[attr]`. +pub enum AttrArgs { + /// No arguments: `#[attr]`. Empty, - /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. - Delimited(DelimSpan, MacDelimiter, TokenStream), - /// Arguments of a key-value attribute - `#[attr = "value"]`. + /// Delimited arguments: `#[attr()/[]/{}]`. + Delimited(DelimArgs), + /// Arguments of a key-value attribute: `#[attr = "value"]`. Eq( /// Span of the `=` token. Span, /// The "value". - MacArgsEq, + AttrArgsEq, ), } -// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion -// is completed, all cases end up either as a literal, which is the form used -// after lowering to HIR, or as an error. +// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro +// expansion is completed, all cases end up either as a literal, which is the +// form used after lowering to HIR, or as an error. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgsEq { +pub enum AttrArgsEq { Ast(P<Expr>), Hir(Lit), } -impl MacArgs { - pub fn delim(&self) -> Option<Delimiter> { - match self { - MacArgs::Delimited(_, delim, _) => Some(delim.to_token()), - MacArgs::Empty | MacArgs::Eq(..) => None, - } - } - +impl AttrArgs { pub fn span(&self) -> Option<Span> { match self { - MacArgs::Empty => None, - MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => None, + AttrArgs::Delimited(args) => Some(args.dspan.entire()), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting span: {:?}", lit); } } @@ -1602,39 +1595,29 @@ impl MacArgs { /// Proc macros see these tokens, for example. pub fn inner_tokens(&self) -> TokenStream { match self { - MacArgs::Empty => TokenStream::default(), - MacArgs::Delimited(.., tokens) => tokens.clone(), - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => TokenStream::default(), + AttrArgs::Delimited(args) => args.tokens.clone(), + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting inner tokens: {:?}", lit) } } } - - /// Whether a macro with these arguments needs a semicolon - /// when used as a standalone item or statement. - pub fn need_semicolon(&self) -> bool { - !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _)) - } } -impl<CTX> HashStable<CTX> for MacArgs +impl<CTX> HashStable<CTX> for AttrArgs where CTX: crate::HashStableContext, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(ctx, hasher); match self { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, delim, tokens) => { - dspan.hash_stable(ctx, hasher); - delim.hash_stable(ctx, hasher); - tokens.hash_stable(ctx, hasher); - } - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => { unreachable!("hash_stable {:?}", expr); } - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } @@ -1642,6 +1625,34 @@ where } } +/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct DelimArgs { + pub dspan: DelimSpan, + pub delim: MacDelimiter, + pub tokens: TokenStream, +} + +impl DelimArgs { + /// Whether a macro with these arguments needs a semicolon + /// when used as a standalone item or statement. + pub fn need_semicolon(&self) -> bool { + !matches!(self, DelimArgs { delim: MacDelimiter::Brace, .. }) + } +} + +impl<CTX> HashStable<CTX> for DelimArgs +where + CTX: crate::HashStableContext, +{ + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + let DelimArgs { dspan, delim, tokens } = self; + dspan.hash_stable(ctx, hasher); + delim.hash_stable(ctx, hasher); + tokens.hash_stable(ctx, hasher); + } +} + #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum MacDelimiter { Parenthesis, @@ -1671,7 +1682,7 @@ impl MacDelimiter { /// Represents a macro definition. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MacroDef { - pub body: P<MacArgs>, + pub body: P<DelimArgs>, /// `true` if macro was defined with `macro_rules`. pub macro_rules: bool, } @@ -2534,7 +2545,7 @@ impl<D: Decoder> Decodable<D> for AttrId { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { pub path: Path, - pub args: MacArgs, + pub args: AttrArgs, pub tokens: Option<LazyAttrTokenStream>, } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index b7be94dde48..2f7c7a29492 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,9 +1,9 @@ //! Functions dealing with attributes and meta items. use crate::ast; -use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; -use crate::ast::{Lit, LitKind}; -use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; +use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; +use crate::ast::{DelimArgs, Lit, LitKind}; +use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Path, PathSegment}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; @@ -158,7 +158,7 @@ impl Attribute { pub fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { - matches!(normal.item.args, MacArgs::Empty) + matches!(normal.item.args, AttrArgs::Empty) } else { false } @@ -223,13 +223,13 @@ impl AttrItem { pub fn meta(&self, span: Span) -> Option<MetaItem> { Some(MetaItem { path: self.path.clone(), - kind: MetaItemKind::from_mac_args(&self.args)?, + kind: MetaItemKind::from_attr_args(&self.args)?, span, }) } pub fn meta_kind(&self) -> Option<MetaItemKind> { - MetaItemKind::from_mac_args(&self.args) + MetaItemKind::from_attr_args(&self.args) } } @@ -390,7 +390,7 @@ pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, path: Path, - args: MacArgs, + args: AttrArgs, span: Span, ) -> Attribute { mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) @@ -413,12 +413,12 @@ pub fn mk_attr_from_item( /// Returns an inner attribute with the given value and span. pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span) + mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span) } /// Returns an outer attribute with the given value and span. pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span) + mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span) } pub fn mk_doc_comment( @@ -524,9 +524,9 @@ impl MetaItemKind { } } - pub fn mac_args(&self, span: Span) -> MacArgs { + pub fn attr_args(&self, span: Span) -> AttrArgs { match self { - MetaItemKind::Word => MacArgs::Empty, + MetaItemKind::Word => AttrArgs::Empty, MetaItemKind::NameValue(lit) => { let expr = P(ast::Expr { id: ast::DUMMY_NODE_ID, @@ -535,7 +535,7 @@ impl MetaItemKind { attrs: ast::AttrVec::new(), tokens: None, }); - MacArgs::Eq(span, MacArgsEq::Ast(expr)) + AttrArgs::Eq(span, AttrArgsEq::Ast(expr)) } MetaItemKind::List(list) => { let mut tts = Vec::new(); @@ -545,11 +545,11 @@ impl MetaItemKind { } tts.extend(item.token_trees()) } - MacArgs::Delimited( - DelimSpan::from_single(span), - MacDelimiter::Parenthesis, - TokenStream::new(tts), - ) + AttrArgs::Delimited(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: MacDelimiter::Parenthesis, + tokens: TokenStream::new(tts), + }) } } } @@ -608,20 +608,22 @@ impl MetaItemKind { } } - fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> { + fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> { match args { - MacArgs::Empty => Some(MetaItemKind::Word), - MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => { - MetaItemKind::list_from_tokens(tokens.clone()) - } - MacArgs::Delimited(..) => None, - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match expr.kind { + AttrArgs::Empty => Some(MetaItemKind::Word), + AttrArgs::Delimited(DelimArgs { + dspan: _, + delim: MacDelimiter::Parenthesis, + tokens, + }) => MetaItemKind::list_from_tokens(tokens.clone()), + AttrArgs::Delimited(..) => None, + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { ast::ExprKind::Lit(token_lit) => Some(MetaItemKind::NameValue( - Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_mac_args"), + Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_attr_args"), )), _ => None, }, - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), } } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index f9ab5a17570..4e1dcb2842f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -367,23 +367,27 @@ pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) { +pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, _delim, tokens) => { - visit_delim_span(dspan, vis); - visit_tts(tokens, vis); - } - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => visit_delim_args(args, vis), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { vis.visit_span(eq_span); vis.visit_expr(expr); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when visiting mac args eq: {:?}", lit) } } } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) { + let DelimArgs { dspan, delim: _, tokens } = args; + visit_delim_span(dspan, vis); + visit_tts(tokens, vis); +} + pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { vis.visit_span(&mut dspan.open); vis.visit_span(&mut dspan.close); @@ -601,7 +605,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = &mut **normal; vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); visit_lazy_tts(attr_tokens, vis); } @@ -613,12 +617,12 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { let MacCall { path, args, prior_type_ascription: _ } = mac; vis.visit_path(path); - visit_mac_args(args, vis); + visit_delim_args(args, vis); } pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { let MacroDef { body, macro_rules: _ } = macro_def; - visit_mac_args(body, vis); + visit_delim_args(body, vis); } pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { @@ -792,7 +796,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T token::NtMeta(item) => { let AttrItem { path, args, tokens } = item.deref_mut(); vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); } token::NtPath(path) => vis.visit_path(path), diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 0978fc94d69..5c69e535212 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -926,17 +926,17 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { match &attr.kind { - AttrKind::Normal(normal) => walk_mac_args(visitor, &normal.item.args), + AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args), AttrKind::DocComment(..) => {} } } -pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) { +pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(_dspan, _delim, _tokens) => {} - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(_) => {} + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when walking mac args eq: {:?}", lit) } } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index eaa5a38388a..3ab42497d6d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -671,7 +671,7 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: AttrKind::Normal(ptr::P(NormalAttr { item: AttrItem { path: Path::from_ident(Ident::new(sym::track_caller, span)), - args: MacArgs::Empty, + args: AttrArgs::Empty, tokens: None, }, tokens: None, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 05022c1a14c..99b3ac864dd 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -470,7 +470,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::TraitAlias(generics, bounds) } ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { - let body = P(self.lower_mac_args(body)); + let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 500737f6e80..ce81a0ae959 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -911,7 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { path: normal.item.path.clone(), - args: self.lower_mac_args(&normal.item.args), + args: self.lower_attr_args(&normal.item.args), tokens: None, }, tokens: None, @@ -931,32 +931,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_mac_args(&self, args: &MacArgs) -> MacArgs { + fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs { match *args { - MacArgs::Empty => MacArgs::Empty, - MacArgs::Delimited(dspan, delim, ref tokens) => { - // This is either a non-key-value attribute, or a `macro_rules!` body. - // We either not have any nonterminals present (in the case of an attribute), - // or have tokens available for all nonterminals in the case of a nested - // `macro_rules`: e.g: - // - // ```rust - // macro_rules! outer { - // ($e:expr) => { - // macro_rules! inner { - // () => { $e } - // } - // } - // } - // ``` - // - // In both cases, we don't want to synthesize any tokens - MacArgs::Delimited(dspan, delim, tokens.flattened()) - } + AttrArgs::Empty => AttrArgs::Empty, + AttrArgs::Delimited(ref args) => AttrArgs::Delimited(self.lower_delim_args(args)), // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(ref expr)) => { // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind { @@ -975,14 +957,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) + AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) } - MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(ref lit)) => { unreachable!("in literal form when lowering mac args eq: {:?}", lit) } } } + fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs { + DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() } + } + /// Given an associated type constraint like one of these: /// /// ```ignore (illustrative) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 5f01f555b30..991f6e0ba22 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -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(), - ¯o_def.body.inner_tokens(), + macro_def.body.delim.to_token(), + ¯o_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(), ); diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 119724b5049..8555c3593b3 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -4,7 +4,7 @@ use crate::edition_panic::use_panic_2021; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; -use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp}; +use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, MacDelimiter, Path, PathSegment, UnOp}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult}; @@ -54,11 +54,11 @@ pub fn expand_assert<'cx>( call_site_span, ExprKind::MacCall(P(MacCall { path: panic_path(), - args: P(MacArgs::Delimited( - DelimSpan::from_single(call_site_span), - MacDelimiter::Parenthesis, + args: P(DelimArgs { + dspan: DelimSpan::from_single(call_site_span), + delim: MacDelimiter::Parenthesis, tokens, - )), + }), prior_type_ascription: None, })), ); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 4b57bdfbc8f..220b7a8ad0f 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -3,7 +3,7 @@ use rustc_ast::{ ptr::P, token, tokenstream::{DelimSpan, TokenStream, TokenTree}, - BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, MethodCall, + BinOpKind, BorrowKind, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MacDelimiter, MethodCall, Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID, }; use rustc_ast_pretty::pprust; @@ -181,11 +181,11 @@ impl<'cx, 'a> Context<'cx, 'a> { self.span, ExprKind::MacCall(P(MacCall { path: panic_path, - args: P(MacArgs::Delimited( - DelimSpan::from_single(self.span), - MacDelimiter::Parenthesis, - initial.into_iter().chain(captures).collect::<TokenStream>(), - )), + args: P(DelimArgs { + dspan: DelimSpan::from_single(self.span), + delim: MacDelimiter::Parenthesis, + tokens: initial.into_iter().chain(captures).collect::<TokenStream>(), + }), prior_type_ascription: None, })), ) diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index 3f1a8b3bc2c..cae648cd11a 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -58,11 +58,11 @@ fn expand<'cx>( .collect(), tokens: None, }, - args: P(MacArgs::Delimited( - DelimSpan::from_single(sp), - MacDelimiter::Parenthesis, - tts, - )), + args: P(DelimArgs { + dspan: DelimSpan::from_single(sp), + delim: MacDelimiter::Parenthesis, + tokens: tts, + }), prior_type_ascription: None, })), ), diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 3d37e2c6568..15dcc584738 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -11,9 +11,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind}; -use rustc_ast::{HasAttrs, HasNodeId}; -use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind}; +use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind}; +use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId}; +use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind}; use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::map_in_place::MapInPlace; @@ -654,7 +654,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ExpandResult::Ready(match invoc.kind { InvocationKind::Bang { mac, .. } => match ext { SyntaxExtensionKind::Bang(expander) => { - let Ok(tok_result) = expander.expand(self.cx, span, mac.args.inner_tokens()) else { + let Ok(tok_result) = expander.expand(self.cx, span, mac.args.tokens.clone()) else { return ExpandResult::Ready(fragment_kind.dummy(span)); }; self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span) @@ -662,7 +662,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { SyntaxExtensionKind::LegacyBang(expander) => { let prev = self.cx.current_expansion.prior_type_ascription; self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription; - let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens()); + let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone()); let result = if let Some(result) = fragment_kind.make_from(tok_result) { result } else { @@ -706,7 +706,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => item.to_tokens(), }; let attr_item = attr.unwrap_normal_item(); - if let MacArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq(..) = attr_item.args { self.cx.span_err(span, "key-value macro attributes are not supported"); } let inner_tokens = attr_item.args.inner_tokens(); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 6c7063ca28b..5da410e41a7 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -577,7 +577,7 @@ pub fn compile_declarative_macro( // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { - ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.inner_tokens()), + ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()), _ => unreachable!(), }; diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index a3c631d3318..e49f112bf20 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -291,7 +291,7 @@ fn ttdelim_span() { .unwrap(); let tts: Vec<_> = match expr.kind { - ast::ExprKind::MacCall(ref mac) => mac.args.inner_tokens().into_trees().collect(), + ast::ExprKind::MacCall(ref mac) => mac.args.tokens.clone().into_trees().collect(), _ => panic!("not a macro"), }; diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 97b1871028e..03bb5c1dfe4 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -16,7 +16,11 @@ pub fn placeholder( fn mac_placeholder() -> P<ast::MacCall> { P(ast::MacCall { path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None }, - args: P(ast::MacArgs::Empty), + args: P(ast::DelimArgs { + dspan: ast::tokenstream::DelimSpan::dummy(), + delim: ast::MacDelimiter::Parenthesis, + tokens: ast::tokenstream::TokenStream::new(Vec::new()), + }), prior_type_ascription: None, }) } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c2d0a662ddb..8c779579a4f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2030,10 +2030,10 @@ impl KeywordIdents { impl EarlyLintPass for KeywordIdents { fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) { - self.check_tokens(cx, mac_def.body.inner_tokens()); + self.check_tokens(cx, mac_def.body.tokens.clone()); } fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) { - self.check_tokens(cx, mac.args.inner_tokens()); + self.check_tokens(cx, mac.args.tokens.clone()); } fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) { self.check_ident_token(cx, UnderMacro(false), ident); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index aa6d378a43a..ba6a3aeb209 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -400,7 +400,7 @@ define_tables! { assoc_container: Table<DefIndex, ty::AssocItemContainer>, // Slot is full when macro is macro_rules. macro_rules: Table<DefIndex, ()>, - macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>, + macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>, proc_macro: Table<DefIndex, MacroKind>, module_reexports: Table<DefIndex, LazyArray<ModChild>>, deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>, diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index e1e705a922f..d6025248081 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -70,7 +70,7 @@ trivially_parameterized_over_tcx! { ty::adjustment::CoerceUnsizedInfo, ty::fast_reject::SimplifiedTypeGen<DefId>, rustc_ast::Attribute, - rustc_ast::MacArgs, + rustc_ast::DelimArgs, rustc_attr::ConstStability, rustc_attr::DefaultBodyStability, rustc_attr::Deprecation, diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index c78479b098b..b49a01d75ed 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -15,8 +15,7 @@ extern crate tracing; use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::Attribute; -use rustc_ast::{AttrItem, MetaItem}; +use rustc_ast::{AttrItem, Attribute, MetaItem}; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult}; @@ -257,10 +256,12 @@ pub fn parse_cfg_attr( parse_sess: &ParseSess, ) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> { match attr.get_normal_item().args { - ast::MacArgs::Delimited(dspan, delim, ref tts) if !tts.is_empty() => { + ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens }) + if !tokens.is_empty() => + { let msg = "wrong `cfg_attr` delimiters"; crate::validate_attr::check_meta_bad_delim(parse_sess, dspan, delim, msg); - match parse_in(parse_sess, tts.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { + match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { Ok(r) => return Some(r), Err(mut e) => { e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index fe7401786a0..ba73fbd3e12 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1501,7 +1501,7 @@ impl<'a> Parser<'a> { let lo = path.span; let mac = P(MacCall { path, - args: self.parse_mac_args()?, + args: self.parse_delim_args()?, prior_type_ascription: self.last_type_ascription, }); (lo.to(self.prev_token.span), ExprKind::MacCall(mac)) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e5f58ca3894..20b01f554f2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -13,7 +13,7 @@ use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind}; use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData}; use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; -use rustc_ast::{MacArgs, MacCall, MacDelimiter}; +use rustc_ast::{MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey}; use rustc_span::edition::Edition; @@ -471,7 +471,7 @@ impl<'a> Parser<'a> { fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> { let path = self.parse_path(PathStyle::Mod)?; // `foo::bar` self.expect(&token::Not)?; // `!` - match self.parse_mac_args() { + match self.parse_delim_args() { // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`. Ok(args) => { self.eat_semi_for_macro_if_needed(&args); @@ -1867,7 +1867,7 @@ impl<'a> Parser<'a> { fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> { let ident = self.parse_ident()?; let body = if self.check(&token::OpenDelim(Delimiter::Brace)) { - self.parse_mac_args()? // `MacBody` + self.parse_delim_args()? // `MacBody` } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { let params = self.parse_token_tree(); // `MacParams` let pspan = params.span(); @@ -1880,7 +1880,7 @@ impl<'a> Parser<'a> { let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>` let tokens = TokenStream::new(vec![params, arrow, body]); let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi()); - P(MacArgs::Delimited(dspan, MacDelimiter::Brace, tokens)) + P(DelimArgs { dspan, delim: MacDelimiter::Brace, tokens }) } else { return self.unexpected(); }; @@ -1935,7 +1935,7 @@ impl<'a> Parser<'a> { .emit(); } - let body = self.parse_mac_args()?; + let body = self.parse_delim_args()?; self.eat_semi_for_macro_if_needed(&body); self.complain_if_pub_macro(vis, true); @@ -1974,14 +1974,14 @@ impl<'a> Parser<'a> { } } - fn eat_semi_for_macro_if_needed(&mut self, args: &MacArgs) { + fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) { if args.need_semicolon() && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(args); } } - fn report_invalid_macro_expansion_item(&self, args: &MacArgs) { - let span = args.span().expect("undelimited macro call"); + fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) { + let span = args.dspan.entire(); let mut err = self.struct_span_err( span, "macros that expand to items must be delimited with braces or followed by a semicolon", @@ -1990,10 +1990,7 @@ impl<'a> Parser<'a> { // macros within the same crate (that we can fix), which is sad. if !span.from_expansion() { if self.unclosed_delims.is_empty() { - let DelimSpan { open, close } = match args { - MacArgs::Empty | MacArgs::Eq(..) => unreachable!(), - MacArgs::Delimited(dspan, ..) => *dspan, - }; + let DelimSpan { open, close } = args.dspan; err.multipart_suggestion( "change the delimiters to curly braces", vec![(open, "{".to_string()), (close, '}'.to_string())], diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 13a38a17735..8878c404c58 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -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_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 { + AttrArgs::Empty + } + }) } - 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 - } - } else { - return self.unexpected(); - }, - ) + 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( diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 0e202645a39..bf52febb107 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -693,7 +693,7 @@ impl<'a> Parser<'a> { /// Parse macro invocation fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> { self.bump(); - let args = self.parse_mac_args()?; + let args = self.parse_delim_args()?; let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); Ok(PatKind::MacCall(mac)) } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 7820bbc1789..73de86820d8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -167,14 +167,13 @@ impl<'a> Parser<'a> { /// Parses a statement macro `mac!(args)` provided a `path` representing `mac`. /// At this point, the `!` token after the path has already been eaten. fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResult<'a, Stmt> { - let args = self.parse_mac_args()?; - let delim = args.delim(); + let args = self.parse_delim_args()?; + let delim = args.delim.to_token(); let hi = self.prev_token.span; let style = match delim { - Some(Delimiter::Brace) => MacStmtStyle::Braces, - Some(_) => MacStmtStyle::NoBraces, - None => unreachable!(), + Delimiter::Brace => MacStmtStyle::Braces, + _ => MacStmtStyle::NoBraces, }; let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d6854f07025..fecf67cb596 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -665,7 +665,7 @@ impl<'a> Parser<'a> { // Macro invocation in type position Ok(TyKind::MacCall(P(MacCall { path, - args: self.parse_mac_args()?, + args: self.parse_delim_args()?, prior_type_ascription: self.last_type_ascription, }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8e7f8bfe0f5..e2f95d74a3d 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -3,7 +3,8 @@ use crate::parse_in; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::{self as ast, Attribute, MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind}; +use rustc_ast::MetaItemKind; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MacDelimiter, MetaItem}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; @@ -24,7 +25,7 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) { Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => { check_builtin_attribute(sess, attr, *name, *template) } - _ if let MacArgs::Eq(..) = attr.get_normal_item().args => { + _ if let AttrArgs::Eq(..) = attr.get_normal_item().args => { // All key-value attributes are restricted to meta-item syntax. parse_meta(sess, attr) .map_err(|mut err| { @@ -42,13 +43,13 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta span: attr.span, path: item.path.clone(), kind: match &item.args { - MacArgs::Empty => MetaItemKind::Word, - MacArgs::Delimited(dspan, delim, t) => { + AttrArgs::Empty => MetaItemKind::Word, + AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => { check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters"); - let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?; + let nmis = parse_in(sess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => { + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { if let ast::ExprKind::Lit(token_lit) = expr.kind && let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span) { @@ -78,7 +79,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta return Err(err); } } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), }, }) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 21f8fbe36f1..35e2720fdff 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -580,7 +580,7 @@ pub(super) fn display_macro_source( def_id: DefId, vis: ty::Visibility<DefId>, ) -> String { - let tts: Vec<_> = def.body.inner_tokens().into_trees().collect(); + let tts: Vec<_> = def.body.tokens.clone().into_trees().collect(); // Extract the spans of all matchers. They represent the "interface" of the macro. let matchers = tts.chunks(4).map(|arm| &arm[0]); diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs index 20cc330e035..b2fe0386f94 100644 --- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs +++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs @@ -55,7 +55,7 @@ impl EarlyLintPass for CrateInMacroDef { if_chain! { if item.attrs.iter().any(is_macro_export); if let ItemKind::MacroDef(macro_def) = &item.kind; - let tts = macro_def.body.inner_tokens(); + let tts = macro_def.body.tokens.clone(); if let Some(span) = contains_unhygienic_crate_reference(&tts); then { span_lint_and_sugg( diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 23aed4b5ba2..87b378bfd19 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -388,7 +388,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind)) }, (MacCall(l), MacCall(r)) => eq_mac_call(l, r), - (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_mac_args(&l.body, &r.body), + (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_delim_args(&l.body, &r.body), _ => false, } } @@ -709,7 +709,7 @@ pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool { } pub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool { - eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args) + eq_path(&l.path, &r.path) && eq_delim_args(&l.args, &r.args) } pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool { @@ -717,18 +717,22 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool { l.style == r.style && match (&l.kind, &r.kind) { (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2, - (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_mac_args(&l.item.args, &r.item.args), + (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args), _ => false, } } -pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool { - use MacArgs::*; +pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool { + use AttrArgs::*; match (l, r) { (Empty, Empty) => true, - (Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts), - (Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re), - (Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind, + (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra), + (Eq(_, AttrArgsEq::Ast(le)), Eq(_, AttrArgsEq::Ast(re))) => eq_expr(le, re), + (Eq(_, AttrArgsEq::Hir(ll)), Eq(_, AttrArgsEq::Hir(rl))) => ll.kind == rl.kind, _ => false, } } + +pub fn eq_delim_args(l: &DelimArgs, r: &DelimArgs) -> bool { + l.delim == r.delim && l.tokens.eq_unspanned(&r.tokens) +} diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index aba1c484bf1..d5611082f01 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -1341,7 +1341,7 @@ pub(crate) fn can_be_overflowed_expr( } ast::ExprKind::MacCall(ref mac) => { match ( - rustc_ast::ast::MacDelimiter::from_token(mac.args.delim().unwrap()), + rustc_ast::ast::MacDelimiter::from_token(mac.args.delim.to_token()), context.config.overflow_delimited_expr(), ) { (Some(ast::MacDelimiter::Bracket), true) diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 3a641fab5d6..df949388037 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -208,7 +208,7 @@ fn rewrite_macro_inner( original_style }; - let ts = mac.args.inner_tokens(); + let ts = mac.args.tokens.clone(); let has_comment = contains_comment(context.snippet(mac.span())); if ts.is_empty() && !has_comment { return match style { @@ -392,7 +392,7 @@ pub(crate) fn rewrite_macro_def( return snippet; } - let ts = def.body.inner_tokens(); + let ts = def.body.tokens.clone(); let mut parser = MacroParser::new(ts.into_trees()); let parsed_def = match parser.parse() { Some(def) => def, @@ -1087,7 +1087,7 @@ pub(crate) fn convert_try_mac( ) -> Option<ast::Expr> { let path = &pprust::path_to_string(&mac.path); if path == "try" || path == "r#try" { - let ts = mac.args.inner_tokens(); + let ts = mac.args.tokens.clone(); Some(ast::Expr { id: ast::NodeId::root(), // dummy value diff --git a/src/tools/rustfmt/src/parse/macros/asm.rs b/src/tools/rustfmt/src/parse/macros/asm.rs index cc9fb5072ce..01edfab3654 100644 --- a/src/tools/rustfmt/src/parse/macros/asm.rs +++ b/src/tools/rustfmt/src/parse/macros/asm.rs @@ -5,7 +5,7 @@ use crate::rewrite::RewriteContext; #[allow(dead_code)] pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> { - let ts = mac.args.inner_tokens(); + let ts = mac.args.tokens.clone(); let mut parser = super::build_parser(context, ts); parse_asm_args(&mut parser, context.parse_sess.inner(), mac.span(), false).ok() } diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs index 09b3e32df31..ace1a76b3fe 100644 --- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs +++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs @@ -23,7 +23,7 @@ fn parse_cfg_if_inner<'a>( sess: &'a ParseSess, mac: &'a ast::MacCall, ) -> Result<Vec<ast::Item>, &'static str> { - let ts = mac.args.inner_tokens(); + let ts = mac.args.tokens.clone(); let mut parser = build_stream_parser(sess.inner(), ts); let mut items = vec![]; |
