Rollup merge of #133746 - oli-obk:push-xwyrylxmrtvq, r=jieyouxu

Change `AttrArgs::Eq` to a struct variant

Cleanups for simplifying https://github.com/rust-lang/rust/pull/131808

Basically changes `AttrArgs::Eq` to a struct variant and then avoids several matches on `AttrArgsEq` in favor of methods on it. This will make future refactorings simpler, as they can either keep methods or switch to field accesses without having to restructure code
This commit is contained in:
Guillaume Gomez 2024-12-02 23:08:58 +01:00 committed by GitHub
commit 6f9f17fc08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 68 additions and 52 deletions

View file

@ -1731,12 +1731,12 @@ pub enum AttrArgs {
/// Delimited arguments: `#[attr()/[]/{}]`.
Delimited(DelimArgs),
/// Arguments of a key-value attribute: `#[attr = "value"]`.
Eq(
Eq {
/// Span of the `=` token.
Span,
/// The "value".
AttrArgsEq,
),
eq_span: Span,
value: AttrArgsEq,
},
}
// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
@ -1748,15 +1748,39 @@ pub enum AttrArgsEq {
Hir(MetaItemLit),
}
impl AttrArgsEq {
pub fn span(&self) -> Span {
match self {
AttrArgsEq::Ast(p) => p.span,
AttrArgsEq::Hir(lit) => lit.span,
}
}
pub fn unwrap_ast(&self) -> &Expr {
match self {
AttrArgsEq::Ast(p) => p,
AttrArgsEq::Hir(lit) => {
unreachable!("in literal form when getting inner tokens: {lit:?}")
}
}
}
pub fn unwrap_ast_mut(&mut self) -> &mut P<Expr> {
match self {
AttrArgsEq::Ast(p) => p,
AttrArgsEq::Hir(lit) => {
unreachable!("in literal form when getting inner tokens: {lit:?}")
}
}
}
}
impl AttrArgs {
pub fn span(&self) -> Option<Span> {
match self {
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);
}
AttrArgs::Eq { eq_span, value } => Some(eq_span.to(value.span())),
}
}
@ -1766,10 +1790,7 @@ impl AttrArgs {
match self {
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)
}
AttrArgs::Eq { value, .. } => TokenStream::from_ast(value.unwrap_ast()),
}
}
}
@ -1783,10 +1804,10 @@ where
match self {
AttrArgs::Empty => {}
AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher),
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => {
AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => {
unreachable!("hash_stable {:?}", expr);
}
AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => {
AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) } => {
eq_span.hash_stable(ctx, hasher);
lit.hash_stable(ctx, hasher);
}

View file

@ -250,7 +250,7 @@ impl AttrItem {
AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => {
MetaItemKind::list_from_tokens(args.tokens.clone())
}
AttrArgs::Delimited(_) | AttrArgs::Eq(..) | AttrArgs::Empty => None,
AttrArgs::Delimited(_) | AttrArgs::Eq { .. } | AttrArgs::Empty => None,
}
}
@ -268,7 +268,7 @@ impl AttrItem {
/// ```
fn value_str(&self) -> Option<Symbol> {
match &self.args {
AttrArgs::Eq(_, args) => args.value_str(),
AttrArgs::Eq { value, .. } => value.value_str(),
AttrArgs::Delimited(_) | AttrArgs::Empty => None,
}
}
@ -492,7 +492,7 @@ impl MetaItemKind {
MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List)
}
AttrArgs::Delimited(..) => None,
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => match expr.kind {
ExprKind::Lit(token_lit) => {
// Turn failures to `None`, we'll get parse errors elsewhere.
MetaItemLit::from_token_lit(token_lit, expr.span)
@ -501,7 +501,9 @@ impl MetaItemKind {
}
_ => None,
},
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
Some(MetaItemKind::NameValue(lit.clone()))
}
}
}
}
@ -702,7 +704,7 @@ pub fn mk_attr_name_value_str(
tokens: None,
});
let path = Path::from_ident(Ident::new(name, span));
let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr));
let args = AttrArgs::Eq { eq_span: span, value: AttrArgsEq::Ast(expr) };
mk_attr(g, style, unsafety, path, args, span)
}

View file

@ -451,13 +451,10 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
match args {
AttrArgs::Empty => {}
AttrArgs::Delimited(args) => visit_delim_args(vis, args),
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
vis.visit_expr(expr);
AttrArgs::Eq { eq_span, value } => {
vis.visit_expr(value.unwrap_ast_mut());
vis.visit_span(eq_span);
}
AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
}
}
}

View file

@ -1273,10 +1273,7 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
match args {
AttrArgs::Empty => {}
AttrArgs::Delimited(_args) => {}
AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)),
AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when walking mac args eq: {:?}", lit)
}
AttrArgs::Eq { value, .. } => try_visit!(visitor.visit_expr(value.unwrap_ast())),
}
V::Result::output()
}

View file

@ -889,7 +889,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// 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]`).
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
&AttrArgs::Eq { eq_span, ref value } => {
let expr = value.unwrap_ast();
// 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
@ -905,10 +906,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: DUMMY_SP,
}
};
AttrArgs::Eq(*eq_span, AttrArgsEq::Hir(lit))
}
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
AttrArgs::Eq { eq_span, value: AttrArgsEq::Hir(lit) }
}
}
}

View file

@ -648,14 +648,14 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
AttrArgs::Empty => {
self.print_path(&item.path, false, 0);
}
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
AttrArgs::Eq { value: 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);
}
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => {
AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
self.print_path(&item.path, false, 0);
self.space();
self.word_space("=");

View file

@ -732,7 +732,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
_ => item.to_tokens(),
};
let attr_item = attr.unwrap_normal_item();
if let AttrArgs::Eq(..) = attr_item.args {
if let AttrArgs::Eq { .. } = attr_item.args {
self.cx.dcx().emit_err(UnsupportedKeyValue { span });
}
let inner_tokens = attr_item.args.inner_tokens();

View file

@ -1376,7 +1376,7 @@ impl<'a> Parser<'a> {
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()?))
AttrArgs::Eq { eq_span, value: AttrArgsEq::Ast(self.parse_expr_force_collect()?) }
} else {
AttrArgs::Empty
})

View file

@ -43,7 +43,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
}
}
_ => {
if let AttrArgs::Eq(..) = attr_item.args {
if let AttrArgs::Eq { .. } = attr_item.args {
// All key-value attributes are restricted to meta-item syntax.
match parse_meta(psess, attr) {
Ok(_) => {}
@ -70,7 +70,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;
MetaItemKind::List(nmis)
}
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
AttrArgs::Eq { value: AttrArgsEq::Ast(expr), .. } => {
if let ast::ExprKind::Lit(token_lit) = expr.kind {
let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span);
let res = match res {
@ -116,7 +116,9 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
return Err(err);
}
}
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()),
AttrArgs::Eq { value: AttrArgsEq::Hir(lit), .. } => {
MetaItemKind::NameValue(lit.clone())
}
},
})
}

View file

@ -220,9 +220,9 @@ pub fn attrs_to_doc_fragments<'a>(
fn span_for_value(attr: &ast::Attribute) -> Span {
if let ast::AttrKind::Normal(normal) = &attr.kind
&& let ast::AttrArgs::Eq(_, ast::AttrArgsEq::Hir(meta)) = &normal.item.args
&& let ast::AttrArgs::Eq { value, .. } = &normal.item.args
{
meta.span.with_ctxt(attr.span.ctxt())
value.span().with_ctxt(attr.span.ctxt())
} else {
attr.span
}

View file

@ -1,7 +1,7 @@
use std::iter;
use std::path::PathBuf;
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, MetaItemInner};
use rustc_ast::{AttrArgs, AttrKind, Attribute, MetaItemInner};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::codes::*;
use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
@ -639,8 +639,7 @@ impl<'tcx> OnUnimplementedDirective {
let report_span = match &item.args {
AttrArgs::Empty => item.path.span,
AttrArgs::Delimited(args) => args.dspan.entire(),
AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => eq_span.to(expr.span),
AttrArgs::Eq(span, AttrArgsEq::Hir(expr)) => span.to(expr.span),
AttrArgs::Eq { eq_span, value } => eq_span.to(value.span()),
};
if let Some(item_def_id) = item_def_id.as_local() {

View file

@ -2647,7 +2647,7 @@ fn filter_doc_attr(normal: &mut ast::NormalAttr, is_inline: bool) {
});
args.tokens = TokenStream::new(tokens);
}
ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => {}
ast::AttrArgs::Empty | ast::AttrArgs::Eq { .. } => {}
}
}

View file

@ -9,7 +9,7 @@ use rustc_span::sym;
pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
if let AttrKind::Normal(normal_attr) = &attr.kind {
if let AttrArgs::Eq(_, AttrArgsEq::Ast(_)) = &normal_attr.item.args {
if let AttrArgs::Eq { value: AttrArgsEq::Ast(_), .. } = &normal_attr.item.args {
// `#[should_panic = ".."]` found, good
return;
}

View file

@ -12,7 +12,7 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
if !attr.span.from_expansion()
&& let AttrKind::Normal(ref normal) = attr.kind
&& normal.item.path == sym::doc
&& let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
&& !attr.span.contains(meta.span)
// Since the `include_str` is already expanded at this point, we can only take the
// whole attribute snippet and then modify for our suggestion.

View file

@ -96,7 +96,7 @@ impl LateLintPass<'_> for LargeIncludeFile {
&& let AttrKind::Normal(ref normal) = attr.kind
&& let Some(doc) = attr.doc_str()
&& doc.as_str().len() as u64 > self.max_file_size
&& let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
&& !attr.span.contains(meta.span)
// Since the `include_str` is already expanded at this point, we can only take the
// whole attribute snippet and then modify for our suggestion.

View file

@ -872,8 +872,8 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
match (l, r) {
(Empty, Empty) => true,
(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,
(Eq { value: AttrArgsEq::Ast(le), .. }, Eq{ value: AttrArgsEq::Ast(re), .. }) => eq_expr(le, re),
(Eq { value: AttrArgsEq::Hir(ll), .. }, Eq{ value: AttrArgsEq::Hir(rl), .. }) => ll.kind == rl.kind,
_ => false,
}
}