From da1a5df7dcdb417e7033ccf3247ff5cfd64e5890 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 24 Aug 2026 13:02:57 +0000 Subject: [PATCH 01/19] take `&Item` instead of `Annotatable` as derive macro input --- .../src/deriving/bounds.rs | 4 +- .../src/deriving/clone.rs | 51 ++++----- .../src/deriving/cmp/eq.rs | 2 +- .../src/deriving/cmp/ord.rs | 2 +- .../src/deriving/cmp/partial_eq.rs | 2 +- .../src/deriving/cmp/partial_ord.rs | 49 ++++----- .../src/deriving/coerce_pointee.rs | 10 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 12 +- .../rustc_builtin_macros/src/deriving/from.rs | 8 +- .../src/deriving/generic/mod.rs | 103 ++++++++---------- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/mod.rs | 9 +- .../src/deriving/reborrow.rs | 39 +++---- 14 files changed, 130 insertions(+), 165 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 48fdb4dd39ce2..5b71d38c63e2e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -9,7 +9,7 @@ pub(crate) fn expand_deriving_copy( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { @@ -34,7 +34,7 @@ pub(crate) fn expand_deriving_const_param_ty( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index b4374e32f6051..be70cf0b584a1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_clone( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { @@ -32,35 +32,30 @@ pub(crate) fn expand_deriving_clone( let bounds; let substructure; let is_simple; - match item { - Annotatable::Item(annitem) => match &annitem.kind { - ItemKind::Struct(_, Generics { params, .. }, _) - | ItemKind::Enum(_, Generics { params, .. }, _) => { - let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); - let has_derive_copy = cx.resolver.has_derive_copy(container_id); - bounds = smallvec![]; - if has_derive_copy - && !params - .iter() - .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) - { - is_simple = true; - substructure = - combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, false)); - } else { - is_simple = false; - substructure = combine_substructure(cs_clone); - } - } - ItemKind::Union(..) => { - bounds = smallvec![Path(path_std!(marker::Copy))]; + match &item.kind { + ItemKind::Struct(_, Generics { params, .. }, _) + | ItemKind::Enum(_, Generics { params, .. }, _) => { + let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); + let has_derive_copy = cx.resolver.has_derive_copy(container_id); + bounds = smallvec![]; + if has_derive_copy + && !params + .iter() + .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) + { is_simple = true; - substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, true)); + substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, false)); + } else { + is_simple = false; + substructure = combine_substructure(cs_clone); } - _ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on wrong item kind"), - }, - - _ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on trait item or impl item"), + } + ItemKind::Union(..) => { + bounds = smallvec![Path(path_std!(marker::Copy))]; + is_simple = true; + substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, true)); + } + _ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on wrong item kind"), } // If the clone method is just copying the value, also mark the type as diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 440360ca85d7d..0df5767e2bde0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_eq( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index a1b38ceadb228..84e5485020a1f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -11,7 +11,7 @@ pub(crate) fn expand_deriving_ord( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index b852e29b03ca4..fb3d6e9b338f7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -13,7 +13,7 @@ pub(crate) fn expand_deriving_partial_eq( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 88141224fddc2..8b778a014ade0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -11,7 +11,7 @@ pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { @@ -20,9 +20,7 @@ pub(crate) fn expand_deriving_partial_ord( Path(Path::new_(pathvec!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std)); // Order in which to perform matching - let discr_then_data = if let Annotatable::Item(item) = item - && let ItemKind::Enum(_, _, def) = &item.kind - { + let discr_then_data = if let ItemKind::Enum(_, _, def) = &item.kind { let dataful: Vec = def.variants.iter().map(|v| !v.data.fields().is_empty()).collect(); match dataful.iter().filter(|&&b| b).count() { // No data, placing the discriminant check first makes codegen simpler @@ -49,29 +47,26 @@ pub(crate) fn expand_deriving_partial_ord( let simple_substructure = combine_substructure(|cx, span, _| { cs_partial_cmp_simple(cx, span, cx.expr_ident(span, Ident::new(sym::other, span))) }); - let is_simple = match item { - Annotatable::Item(annitem) => match &annitem.kind { - // For unit structs/zero-variant enums, the default generated code is better. - ItemKind::Struct(.., ast::VariantData::Unit(..)) => false, - // Also for single fieldless variant enum - ItemKind::Enum(.., enum_def) if enum_def.variants.is_empty() => false, - ItemKind::Enum(.., enum_def) - if enum_def.variants.len() == 1 - && matches!(enum_def.variants[0].data, ast::VariantData::Unit(..)) => - { - false - } - ItemKind::Struct(_, ast::Generics { params, .. }, _) - | ItemKind::Enum(_, ast::Generics { params, .. }, _) - if has_derive_ord - && !params - .iter() - .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) => - { - true - } - _ => false, - }, + let is_simple = match &item.kind { + // For unit structs/zero-variant enums, the default generated code is better. + ItemKind::Struct(.., ast::VariantData::Unit(..)) => false, + // Also for single fieldless variant enum + ItemKind::Enum(.., enum_def) if enum_def.variants.is_empty() => false, + ItemKind::Enum(.., enum_def) + if enum_def.variants.len() == 1 + && matches!(enum_def.variants[0].data, ast::VariantData::Unit(..)) => + { + false + } + ItemKind::Struct(_, ast::Generics { params, .. }, _) + | ItemKind::Enum(_, ast::Generics { params, .. }, _) + if has_derive_ord + && !params + .iter() + .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) => + { + true + } _ => false, }; diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 80296a43ee490..a18af8e035c68 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -1,6 +1,6 @@ use ast::HasAttrs; use rustc_ast::mut_visit::MutVisitor; -use rustc_ast::visit::BoundKind; +use rustc_ast::visit::{BoundKind, Visitor}; use rustc_ast::{ self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, MetaItem, TraitBoundModifiers, VariantData, WherePredicate, @@ -22,15 +22,13 @@ pub(crate) fn expand_deriving_coerce_pointee( cx: &ExtCtxt<'_>, span: Span, _mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), _is_const: bool, ) { - item.visit_with(&mut DetectNonGenericPointeeAttr { cx }); + DetectNonGenericPointeeAttr { cx }.visit_item(item); - let (name_ident, generics) = if let Annotatable::Item(aitem) = item - && let ItemKind::Struct(ident, g, struct_data) = &aitem.kind - { + let (name_ident, generics) = if let ItemKind::Struct(ident, g, struct_data) = &item.kind { if !matches!( struct_data, VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _) diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 94e0b704e6c08..74dd639298d1c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_debug( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 3e4c5f1dcfa53..4293c89d15f96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -1,6 +1,6 @@ use core::ops::ControlFlow; -use rustc_ast::visit::visit_opt; +use rustc_ast::visit::{Visitor, visit_opt}; use rustc_ast::{self as ast, EnumDef, Safety, VariantData, attr}; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; @@ -15,11 +15,11 @@ pub(crate) fn expand_deriving_default( cx: &ExtCtxt<'_>, span: Span, mitem: &ast::MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { - item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); + DetectNonVariantDefaultAttr { cx }.visit_item(item); let trait_def = TraitDef { span, @@ -42,7 +42,7 @@ pub(crate) fn expand_deriving_default( default_struct_substructure(cx, trait_span, substr, fields) } StaticEnum(enum_def) => { - default_enum_substructure(cx, trait_span, enum_def, item.span()) + default_enum_substructure(cx, trait_span, enum_def, item.span) } _ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"), } @@ -308,7 +308,7 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, ' } } -fn has_a_default_variant(item: &Annotatable) -> bool { +fn has_a_default_variant(item: &ast::Item) -> bool { struct HasDefaultAttrOnVariant; impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant { @@ -323,5 +323,5 @@ fn has_a_default_variant(item: &Annotatable) -> bool { } } - item.visit_with(&mut HasDefaultAttrOnVariant).is_break() + HasDefaultAttrOnVariant.visit_item(item).is_break() } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 9824ab5a225b7..4f7d7fe15b616 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -16,14 +16,10 @@ pub(crate) fn expand_deriving_from( cx: &ExtCtxt<'_>, span: Span, mitem: &ast::MetaItem, - annotatable: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { - let Annotatable::Item(item) = &annotatable else { - cx.dcx().bug("derive(From) used on something else than an item"); - }; - let err_span = || { let item_span = item.kind.ident().map(|ident| ident.span).unwrap_or(item.span); MultiSpan::from_spans(vec![span, item_span]) @@ -127,5 +123,5 @@ pub(crate) fn expand_deriving_from( document: true, }; - from_trait_def.expand(cx, mitem, annotatable, push); + from_trait_def.expand(cx, mitem, item, push); } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 6a53dafd396df..cfd336fafc4a9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -179,10 +179,11 @@ use std::{iter, vec}; pub(crate) use StaticFields::*; pub(crate) use SubstructureFields::*; +pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentIsRaw, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; use rustc_ast::{ - self as ast, AnonConst, AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg, + AnonConst, AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg, GenericParamKind, Generics, Mutability, PatKind, Safety, SelfKind, VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; @@ -473,7 +474,7 @@ impl<'a> TraitDef<'a> { self, cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, - item: &'a Annotatable, + item: &'a ast::Item, push: &mut dyn FnMut(Annotatable), ) { self.expand_ext(cx, mitem, item, push, false); @@ -483,72 +484,62 @@ impl<'a> TraitDef<'a> { self, cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, - item: &'a Annotatable, + item: &'a ast::Item, push: &mut dyn FnMut(Annotatable), from_scratch: bool, ) { - match item { - Annotatable::Item(item) => { - let is_packed = matches!( - AttributeParser::parse_limited_sym(cx.sess, &item.attrs, &[sym::repr]), - Some(Attribute::Parsed(AttributeKind::Repr { reprs, .. })) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..))) - ); + let is_packed = matches!( + AttributeParser::parse_limited_sym(cx.sess, &item.attrs, &[sym::repr]), + Some(Attribute::Parsed(AttributeKind::Repr { reprs, .. })) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..))) + ); - let mut newitem = match &item.kind { - ast::ItemKind::Struct(ident, generics, struct_def) => self.expand_struct_def( + let mut newitem = match &item.kind { + ast::ItemKind::Struct(ident, generics, struct_def) => { + self.expand_struct_def(cx, struct_def, *ident, generics, from_scratch, is_packed) + } + ast::ItemKind::Enum(ident, generics, enum_def) => { + // We ignore `is_packed` here, because `repr(packed)` + // enums cause an error later on. + // + // This can only cause further compilation errors + // downstream in blatantly illegal code, so it is fine. + self.expand_enum_def(cx, enum_def, *ident, generics, from_scratch) + } + ast::ItemKind::Union(ident, generics, struct_def) => { + if self.supports_unions { + self.expand_struct_def( cx, struct_def, *ident, generics, from_scratch, is_packed, - ), - ast::ItemKind::Enum(ident, generics, enum_def) => { - // We ignore `is_packed` here, because `repr(packed)` - // enums cause an error later on. - // - // This can only cause further compilation errors - // downstream in blatantly illegal code, so it is fine. - self.expand_enum_def(cx, enum_def, *ident, generics, from_scratch) - } - ast::ItemKind::Union(ident, generics, struct_def) => { - if self.supports_unions { - self.expand_struct_def( - cx, - struct_def, - *ident, - generics, - from_scratch, - is_packed, - ) - } else { - cx.dcx().emit_err(diagnostics::DeriveUnion { span: mitem.span }); - return; - } - } - _ => unreachable!(), - }; - // Keep the lint attributes of the previous item to control how the - // generated implementations are linted - newitem.attrs.extend( - item.attrs - .iter() - .filter(|a| { - a.has_any_name(&[ - sym::allow, - sym::warn, - sym::deny, - sym::forbid, - sym::stable, - sym::unstable, - ]) - }) - .cloned(), - ); - push(Annotatable::Item(newitem)) + ) + } else { + cx.dcx().emit_err(diagnostics::DeriveUnion { span: mitem.span }); + return; + } } _ => unreachable!(), - } + }; + // Keep the lint attributes of the previous item to control how the + // generated implementations are linted + newitem.attrs.extend( + item.attrs + .iter() + .filter(|a| { + a.has_any_name(&[ + sym::allow, + sym::warn, + sym::deny, + sym::forbid, + sym::stable, + sym::unstable, + ]) + }) + .cloned(), + ); + push(Annotatable::Item(newitem)) } /// Given that we are deriving a trait `DerivedTrait` for a type like: diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index f1931aa90a435..5e32a12b6fdca 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -11,7 +11,7 @@ pub(crate) fn expand_deriving_hash( cx: &ExtCtxt<'_>, span: Span, mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), is_const: bool, ) { diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 602af919bd4f2..55838e09b304b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -35,7 +35,7 @@ pub(crate) mod partial_ord; pub(crate) mod generic; pub(crate) type BuiltinDeriveFn = - fn(&ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool); + fn(&ExtCtxt<'_>, Span, &MetaItem, &ast::Item, &mut dyn FnMut(Annotatable), bool); pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn); @@ -59,7 +59,7 @@ impl MultiItemModifier for BuiltinDerive { ecx, span, meta_item, - &Annotatable::Item(item), + &item, &mut |a| { // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' // to the function @@ -75,9 +75,10 @@ impl MultiItemModifier for BuiltinDerive { unreachable!("should have already errored on non-item statement") } } - _ => { - (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const); + Annotatable::Item(item) => { + (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const) } + _ => unreachable!(), } ExpandResult::Ready(items) } diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index 9dc1ccf4fd8e6..c1b8dfb53c694 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -15,7 +15,7 @@ pub(crate) fn expand_deriving_reborrow( cx: &ExtCtxt<'_>, span: Span, _mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), _is_const: bool, ) { @@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_coerce_shared( cx: &ExtCtxt<'_>, span: Span, _mitem: &MetaItem, - item: &Annotatable, + item: &ast::Item, push: &mut dyn FnMut(Annotatable), _is_const: bool, ) { @@ -55,25 +55,19 @@ pub(crate) fn expand_deriving_coerce_shared( fn struct_def<'a>( cx: &ExtCtxt<'_>, span: Span, - item: &'a Annotatable, + item: &'a ast::Item, trait_name: Symbol, ) -> Option<(Ident, &'a Generics)> { - match item { - Annotatable::Item(item) => match &item.kind { - ItemKind::Struct(ident, generics, _) => Some((*ident, generics)), - ItemKind::Enum(..) => { - cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "enum" }); - None - } - ItemKind::Union(..) => { - cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "union" }); - None - } - _ => { - cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "item" }); - None - } - }, + match &item.kind { + ItemKind::Struct(ident, generics, _) => Some((*ident, generics)), + ItemKind::Enum(..) => { + cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "enum" }); + None + } + ItemKind::Union(..) => { + cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "union" }); + None + } _ => { cx.dcx().emit_err(UnsupportedItem { span, trait_name, kind: "item" }); None @@ -81,12 +75,7 @@ fn struct_def<'a>( } } -fn coerce_shared_target(cx: &ExtCtxt<'_>, span: Span, item: &Annotatable) -> Option> { - let Annotatable::Item(item) = item else { - cx.dcx().emit_err(MissingTarget { span }); - return None; - }; - +fn coerce_shared_target(cx: &ExtCtxt<'_>, span: Span, item: &ast::Item) -> Option> { let mut attrs = item.attrs.iter().filter(|attr| attr.has_name(sym::coerce_shared)); let Some(attr) = attrs.next() else { cx.dcx().emit_err(MissingTarget { span }); From 12beb43c72bf426162dc9fb888ae17e8fb0617ea Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 24 Aug 2026 13:11:46 +0000 Subject: [PATCH 02/19] take `Box` instead of `Annotatable` as the `push` argument --- .../rustc_builtin_macros/src/deriving/bounds.rs | 6 +++--- .../rustc_builtin_macros/src/deriving/clone.rs | 4 ++-- .../rustc_builtin_macros/src/deriving/cmp/eq.rs | 4 ++-- .../rustc_builtin_macros/src/deriving/cmp/ord.rs | 4 ++-- .../src/deriving/cmp/partial_eq.rs | 4 ++-- .../src/deriving/cmp/partial_ord.rs | 4 ++-- .../src/deriving/coerce_pointee.rs | 10 +++++----- .../rustc_builtin_macros/src/deriving/debug.rs | 4 ++-- .../rustc_builtin_macros/src/deriving/default.rs | 4 ++-- .../rustc_builtin_macros/src/deriving/from.rs | 4 ++-- .../src/deriving/generic/mod.rs | 8 ++++---- .../rustc_builtin_macros/src/deriving/hash.rs | 4 ++-- compiler/rustc_builtin_macros/src/deriving/mod.rs | 15 ++++++++++----- .../rustc_builtin_macros/src/deriving/reborrow.rs | 12 ++++++------ 14 files changed, 46 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 5b71d38c63e2e..da5370e3e7819 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -1,5 +1,5 @@ use rustc_ast::{MetaItem, Safety}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::Span; use crate::deriving::generic::*; @@ -10,7 +10,7 @@ pub(crate) fn expand_deriving_copy( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let trait_def = TraitDef { @@ -35,7 +35,7 @@ pub(crate) fn expand_deriving_const_param_ty( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let trait_def = TraitDef { diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index be70cf0b584a1..f0c274bce5b58 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,6 +1,6 @@ use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, Safety, VariantData}; use rustc_data_structures::fx::FxHashSet; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -13,7 +13,7 @@ pub(crate) fn expand_deriving_clone( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { // The simple form is `fn clone(&self) -> Self { *self }`, possibly with diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 0df5767e2bde0..8c160cb9868bf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -1,6 +1,6 @@ use rustc_ast::{self as ast, MetaItem, Safety}; use rustc_data_structures::fx::FxHashSet; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -13,7 +13,7 @@ pub(crate) fn expand_deriving_eq( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let span = cx.with_def_site_ctxt(span); diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 84e5485020a1f..fb8d425841722 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -1,5 +1,5 @@ use rustc_ast::{MetaItem, Safety}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_ord( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let trait_def = TraitDef { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index fb3d6e9b338f7..8c442f7dbaa5f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -1,5 +1,5 @@ use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability, Safety}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -14,7 +14,7 @@ pub(crate) fn expand_deriving_partial_eq( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let structural_trait_def = TraitDef { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 8b778a014ade0..0e547d441a74b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -1,5 +1,5 @@ use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety, ast}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_partial_ord( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let ordering_ty = Path(path_std!(cmp::Ordering)); diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index a18af8e035c68..58b4734b132c3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -7,7 +7,7 @@ use rustc_ast::{ }; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_errors::E0802; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_macros::Diagnostic; use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -23,7 +23,7 @@ pub(crate) fn expand_deriving_coerce_pointee( span: Span, _mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), _is_const: bool, ) { DetectNonGenericPointeeAttr { cx }.visit_item(item); @@ -102,7 +102,7 @@ pub(crate) fn expand_deriving_coerce_pointee( let trait_path = cx.path_all(span, true, path!(span, core::marker::CoercePointeeValidated), vec![]); let trait_ref = cx.trait_ref(trait_path); - push(Annotatable::Item( + push( cx.item( span, attrs.clone(), @@ -142,7 +142,7 @@ pub(crate) fn expand_deriving_coerce_pointee( items: ThinVec::new(), }), ), - )); + ); } let mut add_impl_block = |generics, trait_symbol, trait_args| { let mut parts = path!(span, core::ops); @@ -165,7 +165,7 @@ pub(crate) fn expand_deriving_coerce_pointee( items: ThinVec::new(), }), ); - push(Annotatable::Item(item)); + push(item); }; // Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 74dd639298d1c..3c80c01aa32b0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -1,5 +1,5 @@ use rustc_ast::{self as ast, EnumDef, MetaItem, Safety}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_session::config::FmtDebug; use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -13,7 +13,7 @@ pub(crate) fn expand_deriving_debug( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { // &mut ::std::fmt::Formatter diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 4293c89d15f96..88e9d8daf1bd9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -2,7 +2,7 @@ use core::ops::ControlFlow; use rustc_ast::visit::{Visitor, visit_opt}; use rustc_ast::{self as ast, EnumDef, Safety, VariantData, attr}; -use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; +use rustc_expand::base::{DummyResult, ExtCtxt}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use smallvec::SmallVec; use thin_vec::{ThinVec, thin_vec}; @@ -16,7 +16,7 @@ pub(crate) fn expand_deriving_default( span: Span, mitem: &ast::MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { DetectNonVariantDefaultAttr { cx }.visit_item(item); diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 4f7d7fe15b616..ab5008f90ff00 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_ast::{ItemKind, Safety, VariantData}; use rustc_errors::MultiSpan; -use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; +use rustc_expand::base::{DummyResult, ExtCtxt}; use rustc_span::{Ident, Span, kw, sym}; use thin_vec::thin_vec; @@ -17,7 +17,7 @@ pub(crate) fn expand_deriving_from( span: Span, mitem: &ast::MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let err_span = || { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index cfd336fafc4a9..436881dbf2209 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -188,7 +188,7 @@ use rustc_ast::{ }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; use rustc_attr_parsing::AttributeParser; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, respan, sym}; pub(crate) use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; @@ -475,7 +475,7 @@ impl<'a> TraitDef<'a> { cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, item: &'a ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), ) { self.expand_ext(cx, mitem, item, push, false); } @@ -485,7 +485,7 @@ impl<'a> TraitDef<'a> { cx: &ExtCtxt<'_>, mitem: &ast::MetaItem, item: &'a ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), from_scratch: bool, ) { let is_packed = matches!( @@ -539,7 +539,7 @@ impl<'a> TraitDef<'a> { }) .cloned(), ); - push(Annotatable::Item(newitem)) + push(newitem); } /// Given that we are deriving a trait `DerivedTrait` for a type like: diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 5e32a12b6fdca..6864b05ae08cd 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,5 +1,5 @@ use rustc_ast::{MetaItem, Mutability, Safety}; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -12,7 +12,7 @@ pub(crate) fn expand_deriving_hash( span: Span, mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), is_const: bool, ) { let path = path_std!(hash::Hash); diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 55838e09b304b..7c010f62bfd15 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -35,7 +35,7 @@ pub(crate) mod partial_ord; pub(crate) mod generic; pub(crate) type BuiltinDeriveFn = - fn(&ExtCtxt<'_>, Span, &MetaItem, &ast::Item, &mut dyn FnMut(Annotatable), bool); + fn(&ExtCtxt<'_>, Span, &MetaItem, &ast::Item, &mut dyn FnMut(Box), bool); pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn); @@ -65,7 +65,7 @@ impl MultiItemModifier for BuiltinDerive { // to the function items.push(Annotatable::Stmt(Box::new(ast::Stmt { id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Item(a.expect_item()), + kind: ast::StmtKind::Item(a), span, }))); }, @@ -75,9 +75,14 @@ impl MultiItemModifier for BuiltinDerive { unreachable!("should have already errored on non-item statement") } } - Annotatable::Item(item) => { - (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const) - } + Annotatable::Item(item) => (self.0)( + ecx, + span, + meta_item, + &item, + &mut |a| items.push(Annotatable::Item(a)), + is_derive_const, + ), _ => unreachable!(), } ExpandResult::Ready(items) diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index c1b8dfb53c694..43d24417acc00 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -2,7 +2,7 @@ use rustc_ast::{ self as ast, AttrArgs, GenericArg, GenericParamKind, Generics, ItemKind, MetaItem, token, }; use rustc_errors::E0802; -use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_macros::Diagnostic; use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::ThinVec; @@ -16,7 +16,7 @@ pub(crate) fn expand_deriving_reborrow( span: Span, _mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), _is_const: bool, ) { let Some((ident, generics)) = struct_def(cx, span, item, sym::Reborrow) else { @@ -31,7 +31,7 @@ pub(crate) fn expand_deriving_coerce_shared( span: Span, _mitem: &MetaItem, item: &ast::Item, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), _is_const: bool, ) { let Some((ident, generics)) = struct_def(cx, span, item, sym::CoerceShared) else { @@ -119,7 +119,7 @@ fn push_marker_impl( generics: &Generics, trait_name: Symbol, trait_args: Vec, - push: &mut dyn FnMut(Annotatable), + push: &mut dyn FnMut(Box), ) { let mut trait_parts = path!(span, core::marker); trait_parts.push(Ident::new(trait_name, span)); @@ -143,7 +143,7 @@ fn push_marker_impl( .collect(); let self_ty = cx.ty_path(cx.path_all(span, false, vec![ident], self_params)); - push(Annotatable::Item(cx.item( + push(cx.item( span, thin_vec::thin_vec![cx.attr_word(sym::automatically_derived, span)], ast::ItemKind::Impl(ast::Impl { @@ -158,7 +158,7 @@ fn push_marker_impl( self_ty, items: ThinVec::new(), }), - ))); + )); } fn impl_generics(cx: &ExtCtxt<'_>, generics: &Generics) -> Generics { From 6221469c4f435c98dcce2341d95f081e39592b57 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Wed, 26 Aug 2026 11:24:54 +0000 Subject: [PATCH 03/19] several small cleanups --- .../src/deriving/cmp/partial_eq.rs | 12 +++++------- compiler/rustc_builtin_macros/src/deriving/from.rs | 2 +- compiler/rustc_builtin_macros/src/deriving/mod.rs | 10 +--------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 8c442f7dbaa5f..a65962bfc9731 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -47,9 +47,7 @@ pub(crate) fn expand_deriving_partial_eq( ret_ty: Path(generic::ty::Path::new_local(sym::bool)), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: combine_substructure(|a, b, c| { - BlockOrExpr::new_expr(get_substructure_equality_expr(a, b, c)) - }), + combine_substructure: combine_substructure(get_substructure_equality_expr), }]; let trait_def = TraitDef { @@ -123,10 +121,10 @@ fn get_substructure_equality_expr( cx: &ExtCtxt<'_>, span: Span, substructure: &Substructure<'_>, -) -> Box { +) -> BlockOrExpr { use SubstructureFields::*; - match substructure.fields { + BlockOrExpr::new_expr(match substructure.fields { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field| { let rhs = get_field_equality_expr(cx, field); @@ -151,7 +149,7 @@ fn get_substructure_equality_expr( EnumDiscr(disc, match_expr) => { let lhs = get_field_equality_expr(cx, disc); let Some(match_expr) = match_expr else { - return lhs; + return BlockOrExpr::new_expr(lhs); }; // Compare the discriminant first (cheaper), then the rest of the // fields. @@ -169,7 +167,7 @@ fn get_substructure_equality_expr( span, "unexpected all-fieldless enum encountered during `derive(PartialEq)` expansion", ), - } + }) } /// Generates an equality comparison expression for a single struct or enum diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index ab5008f90ff00..0758ff0269a96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -75,7 +75,7 @@ pub(crate) fn expand_deriving_from( supports_unions: false, methods: smallvec![MethodDef { name: sym::from, - generics: Bounds { bounds: vec![] }, + generics: Bounds::empty(), explicit_self: false, nonself_args: smallvec![(from_type, sym::value)], ret_ty: Ty::Self_, diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 7c010f62bfd15..75bd98893de80 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -60,15 +60,7 @@ impl MultiItemModifier for BuiltinDerive { span, meta_item, &item, - &mut |a| { - // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' - // to the function - items.push(Annotatable::Stmt(Box::new(ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Item(a), - span, - }))); - }, + &mut |a| items.push(Annotatable::Stmt(Box::new(ecx.stmt_item(span, a)))), is_derive_const, ); } else { From a054d6fa5792d4c4bfb9af4a019447b8d19648fd Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 10:02:57 +0000 Subject: [PATCH 04/19] remove one use of `expand_ext` --- compiler/rustc_builtin_macros/src/deriving/clone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index f0c274bce5b58..f072b4b9e5cd1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -77,7 +77,7 @@ pub(crate) fn expand_deriving_clone( document: false, }; - trivial_def.expand_ext(cx, mitem, item, push, true); + trivial_def.expand(cx, mitem, item, push); } let trait_def = TraitDef { From 2bc7a8762f91d4bf92b5b7c07465aa9fd43182c5 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 11:54:24 +0000 Subject: [PATCH 05/19] dissolve the `cmp` subdirectory --- .../rustc_builtin_macros/src/deriving/{cmp => }/eq.rs | 0 compiler/rustc_builtin_macros/src/deriving/mod.rs | 9 ++------- .../rustc_builtin_macros/src/deriving/{cmp => }/ord.rs | 0 .../src/deriving/{cmp => }/partial_eq.rs | 0 .../src/deriving/{cmp => }/partial_ord.rs | 0 5 files changed, 2 insertions(+), 7 deletions(-) rename compiler/rustc_builtin_macros/src/deriving/{cmp => }/eq.rs (100%) rename compiler/rustc_builtin_macros/src/deriving/{cmp => }/ord.rs (100%) rename compiler/rustc_builtin_macros/src/deriving/{cmp => }/partial_eq.rs (100%) rename compiler/rustc_builtin_macros/src/deriving/{cmp => }/partial_ord.rs (100%) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs similarity index 100% rename from compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs rename to compiler/rustc_builtin_macros/src/deriving/eq.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 75bd98893de80..337ee43938bd7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -19,18 +19,13 @@ pub(crate) mod clone; pub(crate) mod coerce_pointee; pub(crate) mod debug; pub(crate) mod default; +pub(crate) mod eq; pub(crate) mod from; pub(crate) mod hash; -pub(crate) mod reborrow; - -#[path = "cmp/eq.rs"] -pub(crate) mod eq; -#[path = "cmp/ord.rs"] pub(crate) mod ord; -#[path = "cmp/partial_eq.rs"] pub(crate) mod partial_eq; -#[path = "cmp/partial_ord.rs"] pub(crate) mod partial_ord; +pub(crate) mod reborrow; pub(crate) mod generic; diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs similarity index 100% rename from compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs rename to compiler/rustc_builtin_macros/src/deriving/ord.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs similarity index 100% rename from compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs rename to compiler/rustc_builtin_macros/src/deriving/partial_eq.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs similarity index 100% rename from compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs rename to compiler/rustc_builtin_macros/src/deriving/partial_ord.rs From c1867744a9c12aa6f97777be4f9d3d404f8be334 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 12:00:20 +0000 Subject: [PATCH 06/19] split `bounds` module into `const_param_ty` and `copy` modules --- .../deriving/{bounds.rs => const_param_ty.rs} | 25 --------------- .../rustc_builtin_macros/src/deriving/copy.rs | 31 +++++++++++++++++++ .../rustc_builtin_macros/src/deriving/mod.rs | 3 +- compiler/rustc_builtin_macros/src/lib.rs | 4 +-- 4 files changed, 35 insertions(+), 28 deletions(-) rename compiler/rustc_builtin_macros/src/deriving/{bounds.rs => const_param_ty.rs} (56%) create mode 100644 compiler/rustc_builtin_macros/src/deriving/copy.rs diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs similarity index 56% rename from compiler/rustc_builtin_macros/src/deriving/bounds.rs rename to compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs index da5370e3e7819..18a9df86b547e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs @@ -5,31 +5,6 @@ use rustc_span::Span; use crate::deriving::generic::*; use crate::deriving::path_std; -pub(crate) fn expand_deriving_copy( - cx: &ExtCtxt<'_>, - span: Span, - mitem: &MetaItem, - item: &ast::Item, - push: &mut dyn FnMut(Box), - is_const: bool, -) { - let trait_def = TraitDef { - span, - path: path_std!(marker::Copy), - skip_path_as_bound: false, - needs_copy_as_bound_if_packed: false, - additional_bounds: SmallVec::new(), - supports_unions: true, - methods: SmallVec::new(), - associated_types: SmallVec::new(), - is_const, - safety: Safety::Default, - document: true, - }; - - trait_def.expand(cx, mitem, item, push); -} - pub(crate) fn expand_deriving_const_param_ty( cx: &ExtCtxt<'_>, span: Span, diff --git a/compiler/rustc_builtin_macros/src/deriving/copy.rs b/compiler/rustc_builtin_macros/src/deriving/copy.rs new file mode 100644 index 0000000000000..5743d27cf7458 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/deriving/copy.rs @@ -0,0 +1,31 @@ +use rustc_ast::{MetaItem, Safety}; +use rustc_expand::base::ExtCtxt; +use rustc_span::Span; + +use crate::deriving::generic::*; +use crate::deriving::path_std; + +pub(crate) fn expand_deriving_copy( + cx: &ExtCtxt<'_>, + span: Span, + mitem: &MetaItem, + item: &ast::Item, + push: &mut dyn FnMut(Box), + is_const: bool, +) { + let trait_def = TraitDef { + span, + path: path_std!(marker::Copy), + skip_path_as_bound: false, + needs_copy_as_bound_if_packed: false, + additional_bounds: SmallVec::new(), + supports_unions: true, + methods: SmallVec::new(), + associated_types: SmallVec::new(), + is_const, + safety: Safety::Default, + document: true, + }; + + trait_def.expand(cx, mitem, item, push); +} diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 337ee43938bd7..404991903c424 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -14,9 +14,10 @@ macro path_std($($x:tt)*) { generic::ty::Path::new( pathvec!( $($x)* ) ) } -pub(crate) mod bounds; pub(crate) mod clone; pub(crate) mod coerce_pointee; +pub(crate) mod const_param_ty; +pub(crate) mod copy; pub(crate) mod debug; pub(crate) mod default; pub(crate) mod eq; diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index db92413e1b162..57759bb113401 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -133,8 +133,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { register_derive! { Clone: clone::expand_deriving_clone, CoerceShared: reborrow::expand_deriving_coerce_shared, - Copy: bounds::expand_deriving_copy, - ConstParamTy: bounds::expand_deriving_const_param_ty, + Copy: copy::expand_deriving_copy, + ConstParamTy: const_param_ty::expand_deriving_const_param_ty, Debug: debug::expand_deriving_debug, Default: default::expand_deriving_default, Eq: eq::expand_deriving_eq, From 38adf7bdccddf56a557dc141990f748a7701d68a Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 12:35:28 +0000 Subject: [PATCH 07/19] remove last `StaticFields` usage --- .../src/deriving/default.rs | 40 +++++++++++-------- tests/ui/derives/deriving-all-codegen.stdout | 2 +- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 88e9d8daf1bd9..eb9a302be31e0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -38,8 +38,8 @@ pub(crate) fn expand_deriving_default( fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { match substr.fields { - StaticStruct(_, fields) => { - default_struct_substructure(cx, trait_span, substr, fields) + StaticStruct(variant_data, _) => { + default_struct_substructure(cx, trait_span, substr, variant_data) } StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) @@ -66,27 +66,35 @@ fn default_struct_substructure( cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>, - summary: &StaticFields<'_>, + variant_data: &VariantData, ) -> BlockOrExpr { - let expr = match summary { - Unnamed(_, IsTuple::No) => cx.expr_ident(trait_span, substr.type_ident), - Unnamed(fields, IsTuple::Yes) => { - let exprs = fields.iter().map(|sp| default_call(cx, *sp)).collect(); + let expr = match variant_data { + VariantData::Unit(_) => cx.expr_ident(trait_span, substr.type_ident), + VariantData::Tuple(fields, _) => { + let exprs = fields + .iter() + .map(|field| default_call(cx, field.span.with_ctxt(trait_span.ctxt()))) + .collect(); cx.expr_call_ident(trait_span, substr.type_ident, exprs) } - Named(fields) => { + VariantData::Struct { fields, .. } => { let default_fields = fields .iter() - .map(|&(ident, span, default_val)| { - let value = match default_val { - // We use `Default::default()`. - None => default_call(cx, span), + .map(|field| { + let span = field.span.with_ctxt(trait_span.ctxt()); + let value = if let Some(extras) = &field.extras + && let Some(default_val) = &extras.default + { // We use the field default const expression. - Some(val) => { - cx.expr(val.value.span, ast::ExprKind::ConstBlock(val.clone())) - } + cx.expr( + default_val.value.span, + ast::ExprKind::ConstBlock(default_val.clone()), + ) + } else { + // We use `Default::default()`. + default_call(cx, span) }; - cx.field_imm(span, ident, value) + cx.field_imm(span, field.ident.unwrap(), value) }) .collect(); cx.expr_struct_ident(trait_span, substr.type_ident, default_fields) diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 320c1b5861162..54b1976207236 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -46,7 +46,7 @@ impl ::core::fmt::Debug for Empty { #[automatically_derived] impl ::core::default::Default for Empty { #[inline] - fn default() -> Empty { Empty {} } + fn default() -> Empty { Empty } } #[automatically_derived] impl ::core::hash::Hash for Empty { From 3c3c3cdcc75ecd82ef68fc63721cd53aa43b3531 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 12:39:06 +0000 Subject: [PATCH 08/19] remove `StaticFields` and `IsTuple` --- .../src/deriving/default.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 72 ++----------------- 3 files changed, 7 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index eb9a302be31e0..9e65ae0b75cab 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -38,7 +38,7 @@ pub(crate) fn expand_deriving_default( fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { match substr.fields { - StaticStruct(variant_data, _) => { + StaticStruct(variant_data) => { default_struct_substructure(cx, trait_span, substr, variant_data) } StaticEnum(enum_def) => { diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 0758ff0269a96..eb8ddd10d4306 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -91,7 +91,7 @@ pub(crate) fn expand_deriving_from( let self_kw = Ident::new(kw::SelfUpper, span); let expr: Box = match substructure.fields { - SubstructureFields::StaticStruct(variant, _) => match variant { + SubstructureFields::StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( span, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 436881dbf2209..3298b4a583ff8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -177,14 +177,13 @@ use std::ops::Not; use std::{iter, vec}; -pub(crate) use StaticFields::*; pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentIsRaw, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; use rustc_ast::{ - AnonConst, AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg, - GenericParamKind, Generics, Mutability, PatKind, Safety, SelfKind, VariantData, + AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg, GenericParamKind, Generics, + Mutability, PatKind, Safety, SelfKind, VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; use rustc_attr_parsing::AttributeParser; @@ -294,20 +293,6 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } -#[derive(Copy, Clone)] -pub(crate) enum IsTuple { - No, - Yes, -} - -/// Fields for a static method -pub(crate) enum StaticFields<'a> { - /// Tuple and unit structs/enum variants like this. - Unnamed(Vec, IsTuple), - /// Normal structs/struct variants. - Named(Vec<(Ident, Span, Option<&'a AnonConst>)>), -} - /// A summary of the possible sets of fields. pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. @@ -329,7 +314,7 @@ pub(crate) enum SubstructureFields<'a> { EnumDiscr(FieldInfo, Option>), /// A static method where `Self` is a struct. - StaticStruct(&'a ast::VariantData, StaticFields<'a>), + StaticStruct(&'a ast::VariantData), /// A static method where `Self` is an enum. StaticEnum(&'a ast::EnumDef), @@ -860,12 +845,12 @@ impl<'a> TraitDef<'a> { method_def.extract_arg_details(cx, self, type_ident, generics); let body = if from_scratch || method_def.is_static() { - method_def.expand_static_struct_method_body( + method_def.call_substructure_method( cx, self, - struct_def, type_ident, &nonselflike_args, + &StaticStruct(struct_def), ) } else { method_def.expand_struct_method_body( @@ -1133,25 +1118,6 @@ impl<'a> MethodDef<'a> { ) } - fn expand_static_struct_method_body( - &self, - cx: &ExtCtxt<'_>, - trait_: &TraitDef<'a>, - struct_def: &'a VariantData, - type_ident: Ident, - nonselflike_args: &[Box], - ) -> BlockOrExpr { - let summary = trait_.summarise_struct(cx, struct_def); - - self.call_substructure_method( - cx, - trait_, - type_ident, - nonselflike_args, - &StaticStruct(struct_def, summary), - ) - } - /// ``` /// #[derive(PartialEq)] /// # struct Dummy; @@ -1450,34 +1416,6 @@ impl<'a> MethodDef<'a> { // general helper methods. impl<'a> TraitDef<'a> { - fn summarise_struct(&self, cx: &ExtCtxt<'_>, struct_def: &'a VariantData) -> StaticFields<'a> { - let mut named_idents = Vec::new(); - let mut just_spans = Vec::new(); - for field in struct_def.fields() { - let sp = field.span.with_ctxt(self.span.ctxt()); - match field.ident { - Some(ident) => named_idents.push((ident, sp, field.default_value())), - _ => just_spans.push(sp), - } - } - - let is_tuple = match struct_def { - ast::VariantData::Tuple(..) => IsTuple::Yes, - _ => IsTuple::No, - }; - match (just_spans.is_empty(), named_idents.is_empty()) { - (false, false) => cx - .dcx() - .span_bug(self.span, "a struct with named and unnamed fields in generic `derive`"), - // named fields - (_, false) => Named(named_idents), - // unnamed fields - (false, _) => Unnamed(just_spans, is_tuple), - // empty - _ => Named(Vec::new()), - } - } - fn create_struct_patterns( &self, cx: &ExtCtxt<'_>, From 3eea7c8bc81ee9ccd7c27e392a7c8b3b1c176b8f Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 27 Aug 2026 20:16:44 +0000 Subject: [PATCH 09/19] make `expr_for_field` a closure --- .../rustc_builtin_macros/src/deriving/debug.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 3c80c01aa32b0..90741c40d2fa1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -88,20 +88,15 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> // The number of fields that can be handled without an array. const CUTOFF: usize = 5; - fn expr_for_field( - cx: &ExtCtxt<'_>, - field: &FieldInfo, - index: usize, - len: usize, - ) -> Box { - if index < len - 1 { + let expr_for_field = |field: &FieldInfo, index: usize| -> Box { + if index < fields.len() - 1 { field.self_expr.clone() } else { // Unsized types need an extra indirection, but only the last field // may be unsized. cx.expr_addr_of(field.span, field.self_expr.clone()) } - } + }; if fields.is_empty() { // Special case for no fields. @@ -126,7 +121,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> args.push(name); } - let field = expr_for_field(cx, field, i, fields.len()); + let field = expr_for_field(field, i); args.push(field); } let expr = cx.expr_call_global(span, fn_path_debug, args); @@ -142,7 +137,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name)); } - let field = expr_for_field(cx, field, i, fields.len()); + let field = expr_for_field(field, i); value_exprs.push(field); } From 0890086c188ccd9176601694fcfdb1d36f98894a Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 28 Aug 2026 08:31:32 +0000 Subject: [PATCH 10/19] several small tweaks --- .../src/deriving/coerce_pointee.rs | 6 +-- .../src/deriving/generic/mod.rs | 49 +++++-------------- .../src/deriving/partial_eq.rs | 5 +- 3 files changed, 17 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 58b4734b132c3..33531cbdae275 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -328,10 +328,8 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: if let ast::WherePredicateKind::BoundPredicate(bound) = &bound.kind && bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee) { - for bound in &bound.bounds { - if is_maybe_sized_bound(bound) { - return true; - } + if contains_maybe_sized_bound(&bound.bounds) { + return true; } } } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 3298b4a583ff8..c302d35c9bb9a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -903,12 +903,12 @@ impl<'a> TraitDef<'a> { method_def.extract_arg_details(cx, self, type_ident, generics); let body = if from_scratch || method_def.is_static() { - method_def.expand_static_enum_method_body( + method_def.call_substructure_method( cx, self, - enum_def, type_ident, &nonselflike_args, + &StaticEnum(enum_def), ) } else { method_def.expand_enum_method_body( @@ -1395,23 +1395,6 @@ impl<'a> MethodDef<'a> { BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) } } - - fn expand_static_enum_method_body( - &self, - cx: &ExtCtxt<'_>, - trait_: &TraitDef<'_>, - enum_def: &EnumDef, - type_ident: Ident, - nonselflike_args: &[Box], - ) -> BlockOrExpr { - self.call_substructure_method( - cx, - trait_, - type_ident, - nonselflike_args, - &StaticEnum(enum_def), - ) - } } // general helper methods. @@ -1433,7 +1416,6 @@ impl<'a> TraitDef<'a> { let ident = self.mk_pattern_ident(prefix, i); let path = ident.with_span_pos(sp); ( - sp, struct_field.ident, cx.pat( path.span, @@ -1446,28 +1428,21 @@ impl<'a> TraitDef<'a> { match *struct_def { VariantData::Struct { .. } => { let field_pats = pieces_iter - .map(|(sp, ident, pat)| { - if ident.is_none() { - cx.dcx().span_bug( - sp, - "a braced struct with unnamed fields in `derive`", - ); - } - ast::PatField { - ident: ident.unwrap(), - is_shorthand: false, - attrs: ast::AttrVec::new(), - id: ast::DUMMY_NODE_ID, - span: pat.span.with_ctxt(self.span.ctxt()), - pat: Box::new(pat), - is_placeholder: false, - } + .map(|(ident, pat)| ast::PatField { + ident: ident + .expect("a braced struct with unnamed fields in `derive`"), + is_shorthand: false, + attrs: ast::AttrVec::new(), + id: ast::DUMMY_NODE_ID, + span: pat.span.with_ctxt(self.span.ctxt()), + pat: Box::new(pat), + is_placeholder: false, }) .collect(); cx.pat_struct(self.span, struct_path, field_pats) } VariantData::Tuple(..) => { - let subpats = pieces_iter.map(|(_, _, subpat)| subpat).collect(); + let subpats = pieces_iter.map(|(_, subpat)| subpat).collect(); cx.pat_tuple_struct(self.span, struct_path, subpats) } VariantData::Unit(..) => cx.pat_path(self.span, struct_path), diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index a65962bfc9731..f42a4707c2f99 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -141,8 +141,9 @@ fn get_substructure_equality_expr( // with logical AND. fields .iter() - .filter(|field| !field.maybe_scalar) - .fold(fields.iter().filter(|field| field.maybe_scalar).fold(None, combine), combine) + .filter(|field| field.maybe_scalar) + .chain(fields.iter().filter(|field| !field.maybe_scalar)) + .fold(None, combine) // If there are no fields, treat as always equal. .unwrap_or_else(|| cx.expr_bool(span, true)) } From 41ca6ab4b95bf1c626a8a437dc69c3fac3ab7fb8 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 28 Aug 2026 08:33:57 +0000 Subject: [PATCH 11/19] use a named struct instead of a 4-tuple --- .../src/deriving/generic/mod.rs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index c302d35c9bb9a..6b4c7bea5cdeb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -841,7 +841,7 @@ impl<'a> TraitDef<'a> { .methods .iter() .map(|method_def| { - let (explicit_self, selflike_args, nonselflike_args, nonself_arg_tys) = + let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = method_def.extract_arg_details(cx, self, type_ident, generics); let body = if from_scratch || method_def.is_static() { @@ -899,7 +899,7 @@ impl<'a> TraitDef<'a> { .methods .iter() .map(|method_def| { - let (explicit_self, selflike_args, nonselflike_args, nonself_arg_tys) = + let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = method_def.extract_arg_details(cx, self, type_ident, generics); let body = if from_scratch || method_def.is_static() { @@ -938,6 +938,18 @@ impl<'a> TraitDef<'a> { } } +struct ArgDetails { + /// The `&self` arg, if present. + explicit_self: Option, + /// Expressions for `&self` (if present) and also any other + /// args with the same type (e.g. the `other` arg in `PartialEq::eq`). + selflike_args: ThinVec>, + /// Expressions for all the remaining args. + nonselflike_args: Vec>, + /// Additional information about all the args other than `&self`. + nonself_arg_tys: Vec<(Ident, Box)>, +} + impl<'a> MethodDef<'a> { fn call_substructure_method( &self, @@ -957,21 +969,13 @@ impl<'a> MethodDef<'a> { !self.explicit_self } - // The return value includes: - // - explicit_self: The `&self` arg, if present. - // - selflike_args: Expressions for `&self` (if present) and also any other - // args with the same type (e.g. the `other` arg in `PartialEq::eq`). - // - nonselflike_args: Expressions for all the remaining args. - // - nonself_arg_tys: Additional information about all the args other than - // `&self`. fn extract_arg_details( &self, cx: &ExtCtxt<'_>, trait_: &TraitDef<'_>, type_ident: Ident, generics: &Generics, - ) -> (Option, ThinVec>, Vec>, Vec<(Ident, Box)>) - { + ) -> ArgDetails { let mut selflike_args = ThinVec::new(); let mut nonselflike_args = Vec::new(); let mut nonself_arg_tys = Vec::new(); @@ -998,7 +1002,7 @@ impl<'a> MethodDef<'a> { } } - (explicit_self, selflike_args, nonselflike_args, nonself_arg_tys) + ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } } fn create_method( From 0da0c77c8be7db9ae3c63a3387bec0af7b724280 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 3 Sep 2026 19:59:32 +0000 Subject: [PATCH 12/19] unify `span_bug` message format for unreachable substructures --- compiler/rustc_builtin_macros/src/deriving/clone.rs | 9 ++------- compiler/rustc_builtin_macros/src/deriving/debug.rs | 4 +--- .../rustc_builtin_macros/src/deriving/default.rs | 4 +++- .../src/deriving/generic/mod.rs | 5 +---- compiler/rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/partial_eq.rs | 13 +------------ 6 files changed, 9 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index f072b4b9e5cd1..9a240483842be 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -55,7 +55,7 @@ pub(crate) fn expand_deriving_clone( is_simple = true; substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, true)); } - _ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on wrong item kind"), + _ => cx.dcx().span_bug(span, "`derive(Clone)` on wrong item kind"), } // If the clone method is just copying the value, also mark the type as @@ -186,12 +186,7 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> Bl all_fields = af; vdata = &variant.data; } - EnumDiscr(..) | AllFieldlessEnum(..) => { - cx.dcx().span_bug(trait_span, "enum discriminants in `derive(Clone)`") - } - StaticEnum(..) | StaticStruct(..) => { - cx.dcx().span_bug(trait_span, "associated function in `derive(Clone)`") - } + _ => cx.dcx().span_bug(trait_span, "unexpected substructure in `derive(Clone)`"), } let expr = match *vdata { diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 90741c40d2fa1..9769cd325ae5b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -58,9 +58,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Struct(vdata, fields) => (substr.type_ident, *vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr), - EnumDiscr(..) | StaticStruct(..) | StaticEnum(..) => { - cx.dcx().span_bug(span, "nonsensical .fields in `#[derive(Debug)]`") - } + _ => cx.dcx().span_bug(span, "unexpected substructure in `derive(Debug)`"), }; let name = cx.expr_str(span, ident.name); diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 9e65ae0b75cab..4795525cd1cb6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -44,7 +44,9 @@ pub(crate) fn expand_deriving_default( StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) } - _ => cx.dcx().span_bug(trait_span, "method in `derive(Default)`"), + _ => cx + .dcx() + .span_bug(trait_span, "unexpected substructure in `derive(Default)`"), } }), }], diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 6b4c7bea5cdeb..66bc06044ba67 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1605,9 +1605,6 @@ where discr_check_expr } } - StaticEnum(..) | StaticStruct(..) => { - cx.dcx().span_bug(trait_span, "static function in `derive`") - } - AllFieldlessEnum(..) => cx.dcx().span_bug(trait_span, "fieldless enum in `derive`"), + _ => cx.dcx().span_bug(trait_span, "unexpected substructure in `derive`"), } } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 6864b05ae08cd..bb1e71e40b3fb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -68,7 +68,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<' let stmts = thin_vec![call_hash(discr_field.span, discr_field.self_expr.clone())]; (stmts, match_expr.clone()) } - _ => cx.dcx().span_bug(trait_span, "impossible substructure in `derive(Hash)`"), + _ => cx.dcx().span_bug(trait_span, "unexpected substructure in `derive(Hash)`"), }; BlockOrExpr::new_mixed(stmts, match_expr) diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index f42a4707c2f99..cbff488c16e98 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -156,18 +156,7 @@ fn get_substructure_equality_expr( // fields. cx.expr_binary(disc.span, BinOpKind::And, lhs, match_expr.clone()) } - StaticEnum(..) => cx.dcx().span_bug( - span, - "unexpected static enum encountered during `derive(PartialEq)` expansion", - ), - StaticStruct(..) => cx.dcx().span_bug( - span, - "unexpected static struct encountered during `derive(PartialEq)` expansion", - ), - AllFieldlessEnum(..) => cx.dcx().span_bug( - span, - "unexpected all-fieldless enum encountered during `derive(PartialEq)` expansion", - ), + _ => cx.dcx().span_bug(span, "unexpected substructure in `derive(PartialEq)`"), }) } From 600ef0ddec3bc01c83582a0008d28eddc4c1f277 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 31 Aug 2026 20:21:20 +0000 Subject: [PATCH 13/19] remove some clones via owned `Substructure` --- .../src/deriving/clone.rs | 8 +-- .../src/deriving/coerce_pointee.rs | 2 +- .../src/deriving/debug.rs | 6 +- .../src/deriving/default.rs | 2 +- .../rustc_builtin_macros/src/deriving/eq.rs | 8 +-- .../src/deriving/generic/mod.rs | 59 +++++++++---------- .../rustc_builtin_macros/src/deriving/hash.rs | 8 +-- .../rustc_builtin_macros/src/deriving/ord.rs | 2 +- .../src/deriving/partial_eq.rs | 4 +- .../src/deriving/partial_ord.rs | 2 +- 10 files changed, 48 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 9a240483842be..dff4785bd5fa0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -109,7 +109,7 @@ pub(crate) fn expand_deriving_clone( fn cs_clone_simple( cx: &ExtCtxt<'_>, trait_span: Span, - substr: &Substructure<'_>, + substr: Substructure<'_>, is_union: bool, ) -> BlockOrExpr { let mut stmts = ThinVec::new(); @@ -150,7 +150,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match *substr.fields { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -165,7 +165,7 @@ fn cs_clone_simple( BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span)))) } -fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> BlockOrExpr { +fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { let ctor_path; let all_fields; let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]); @@ -179,7 +179,7 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> Bl Struct(vdata_, af) => { ctor_path = cx.path(trait_span, vec![substr.type_ident]); all_fields = af; - vdata = *vdata_; + vdata = vdata_; } EnumMatching(.., variant, af) => { ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 33531cbdae275..ced806a139ed7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -320,7 +320,7 @@ pub(crate) fn expand_deriving_coerce_pointee( // Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`. let gen_args = vec![GenericArg::Type(alt_self_type)]; add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone()); - add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args); + add_impl_block(impl_generics, sym::CoerceUnsized, gen_args); } fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool { diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 9769cd325ae5b..ac409f2403d3e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -45,7 +45,7 @@ pub(crate) fn expand_deriving_debug( trait_def.expand(cx, mitem, item, push) } -fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { +fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { // We want to make sure we have the ctxt set so that we can use unstable methods let span = cx.with_def_site_ctxt(span); @@ -55,7 +55,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> } let (ident, vdata, fields) = match substr.fields { - Struct(vdata, fields) => (substr.type_ident, *vdata, fields), + Struct(vdata, fields) => (substr.type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, substr), _ => cx.dcx().span_bug(span, "unexpected substructure in `derive(Debug)`"), @@ -217,7 +217,7 @@ fn show_fieldless_enum( cx: &ExtCtxt<'_>, span: Span, def: &EnumDef, - substr: &Substructure<'_>, + substr: Substructure<'_>, ) -> BlockOrExpr { let fmt = substr.nonselflike_args[0].clone(); let arms = def diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 4795525cd1cb6..ca0bf631110b8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -67,7 +67,7 @@ fn default_call(cx: &ExtCtxt<'_>, span: Span) -> Box { fn default_struct_substructure( cx: &ExtCtxt<'_>, trait_span: Span, - substr: &Substructure<'_>, + substr: Substructure<'_>, variant_data: &VariantData, ) -> BlockOrExpr { let expr = match variant_data { diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index 8c160cb9868bf..d651a84bb0155 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -49,11 +49,7 @@ pub(crate) fn expand_deriving_eq( trait_def.expand_ext(cx, mitem, item, push, true) } -fn cs_total_eq_assert( - cx: &ExtCtxt<'_>, - trait_span: Span, - substr: &Substructure<'_>, -) -> BlockOrExpr { +fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { let mut stmts = ThinVec::new(); let mut seen_type_names = FxHashSet::default(); let mut process_variant = |variant: &ast::VariantData| { @@ -78,7 +74,7 @@ fn cs_total_eq_assert( } }; - match *substr.fields { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 66bc06044ba67..e8a269b8467d8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -275,7 +275,7 @@ pub(crate) struct Substructure<'a> { /// Verbatim access to any non-selflike arguments, i.e. arguments that /// don't have type `&Self`. pub nonselflike_args: &'a [Box], - pub fields: &'a SubstructureFields<'a>, + pub fields: SubstructureFields<'a>, } /// Summary of the relevant parts of a struct/enum field. @@ -323,10 +323,10 @@ pub(crate) enum SubstructureFields<'a> { /// Combine the values of all the fields together. The last argument is /// all the fields of all the structures. pub(crate) type CombineSubstructureFunc<'a> = - Box, Span, &Substructure<'_>) -> BlockOrExpr + 'a>; + Box, Span, Substructure<'_>) -> BlockOrExpr + 'a>; pub(crate) fn combine_substructure<'a>( - f: impl Fn(&ExtCtxt<'_>, Span, &Substructure<'_>) -> BlockOrExpr + 'a, + f: impl Fn(&ExtCtxt<'_>, Span, Substructure<'_>) -> BlockOrExpr + 'a, ) -> CombineSubstructureFunc<'a> { Box::new(f) } @@ -850,7 +850,7 @@ impl<'a> TraitDef<'a> { self, type_ident, &nonselflike_args, - &StaticStruct(struct_def), + StaticStruct(struct_def), ) } else { method_def.expand_struct_method_body( @@ -908,7 +908,7 @@ impl<'a> TraitDef<'a> { self, type_ident, &nonselflike_args, - &StaticEnum(enum_def), + StaticEnum(enum_def), ) } else { method_def.expand_enum_method_body( @@ -957,12 +957,12 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'_>, type_ident: Ident, nonselflike_args: &[Box], - fields: &SubstructureFields<'_>, + fields: SubstructureFields<'_>, ) -> BlockOrExpr { let span = trait_.span; let substructure = Substructure { type_ident, nonselflike_args, fields }; let f: &CombineSubstructureFunc<'_> = &self.combine_substructure; - f(cx, span, &substructure) + f(cx, span, substructure) } fn is_static(&self) -> bool { @@ -1118,7 +1118,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &Struct(struct_def, selflike_fields), + Struct(struct_def, selflike_fields), ) } @@ -1248,7 +1248,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumDiscr(discr_field, None), + EnumDiscr(discr_field, None), ); discr_let_stmts.append(&mut discr_check.0); return BlockOrExpr(discr_let_stmts, discr_check.1); @@ -1259,7 +1259,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &AllFieldlessEnum(enum_def), + AllFieldlessEnum(enum_def), ); } FieldlessVariantsStrategy::Default => (), @@ -1272,7 +1272,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumMatching(variant, Vec::new()), + EnumMatching(variant, Vec::new()), ); } } @@ -1324,7 +1324,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &substructure, + substructure, ) .into_expr(cx, span); @@ -1345,7 +1345,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumMatching(v, Vec::new()), + EnumMatching(v, Vec::new()), ) .into_expr(cx, span), ) @@ -1391,7 +1391,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumDiscr(discr_field, Some(get_match_expr(selflike_args))), + EnumDiscr(discr_field, Some(get_match_expr(selflike_args))), ); discr_let_stmts.append(&mut discr_check_plus_match.0); BlockOrExpr(discr_let_stmts, discr_check_plus_match.1) @@ -1543,10 +1543,10 @@ impl<'a> TraitDef<'a> { /// The function passed to `cs_fold` is called repeatedly with a value of this /// type. It describes one part of the code generation. The result is always an /// expression. -pub(crate) enum CsFold<'a> { +pub(crate) enum CsFold { /// The basic case: a field expression for one or more selflike args. E.g. /// for `PartialEq::eq` this is something like `self.x == other.x`. - Single(&'a FieldInfo), + Single(FieldInfo), /// The combination of two field expressions. E.g. for `PartialEq::eq` this /// is something like ` && `. @@ -1562,44 +1562,43 @@ pub(crate) fn cs_fold( use_foldl: bool, cx: &ExtCtxt<'_>, trait_span: Span, - substructure: &Substructure<'_>, + substructure: Substructure<'_>, mut f: F, ) -> Box where - F: FnMut(&ExtCtxt<'_>, CsFold<'_>) -> Box, + F: FnMut(&ExtCtxt<'_>, CsFold) -> Box, { match substructure.fields { - EnumMatching(.., all_fields) | Struct(_, all_fields) => { + EnumMatching(.., mut all_fields) | Struct(_, mut all_fields) => { if all_fields.is_empty() { return f(cx, CsFold::Fieldless); } - let (base_field, rest) = if use_foldl { - all_fields.split_first().unwrap() - } else { - all_fields.split_last().unwrap() - }; + let base_field = + if use_foldl { all_fields.remove(0) } else { all_fields.pop().unwrap() }; + let rest = all_fields; let base_expr = f(cx, CsFold::Single(base_field)); - let op = |old, field: &FieldInfo| { + let op = |old, field: FieldInfo| { + let span = field.span; let new = f(cx, CsFold::Single(field)); - f(cx, CsFold::Combine(field.span, old, new)) + f(cx, CsFold::Combine(span, old, new)) }; if use_foldl { - rest.iter().fold(base_expr, op) + rest.into_iter().fold(base_expr, op) } else { - rest.iter().rfold(base_expr, op) + rest.into_iter().rfold(base_expr, op) } } EnumDiscr(discr_field, match_expr) => { let discr_check_expr = f(cx, CsFold::Single(discr_field)); if let Some(match_expr) = match_expr { if use_foldl { - f(cx, CsFold::Combine(trait_span, discr_check_expr, match_expr.clone())) + f(cx, CsFold::Combine(trait_span, discr_check_expr, match_expr)) } else { - f(cx, CsFold::Combine(trait_span, match_expr.clone(), discr_check_expr)) + f(cx, CsFold::Combine(trait_span, match_expr, discr_check_expr)) } } else { discr_check_expr diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index bb1e71e40b3fb..b87fbf88fe8b7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -46,7 +46,7 @@ pub(crate) fn expand_deriving_hash( hash_trait_def.expand(cx, mitem, item, push); } -fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<'_>) -> BlockOrExpr { +fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { let [state_expr] = substr.nonselflike_args else { cx.dcx().span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`"); }; @@ -60,13 +60,13 @@ fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: &Substructure<' let (stmts, match_expr) = match substr.fields { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = - fields.iter().map(|field| call_hash(field.span, field.self_expr.clone())).collect(); + fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); (stmts, None) } EnumDiscr(discr_field, match_expr) => { assert!(discr_field.other_selflike_exprs.is_empty()); - let stmts = thin_vec![call_hash(discr_field.span, discr_field.self_expr.clone())]; - (stmts, match_expr.clone()) + let stmts = thin_vec![call_hash(discr_field.span, discr_field.self_expr)]; + (stmts, match_expr) } _ => cx.dcx().span_bug(trait_span, "unexpected substructure in `derive(Hash)`"), }; diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index fb8d425841722..4d3084a87db43 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -41,7 +41,7 @@ pub(crate) fn expand_deriving_ord( trait_def.expand(cx, mitem, item, push) } -pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { +pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { let test_id = Ident::new(sym::cmp, span); let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal])); let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index cbff488c16e98..76fedf84adc09 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -120,7 +120,7 @@ pub(crate) fn expand_deriving_partial_eq( fn get_substructure_equality_expr( cx: &ExtCtxt<'_>, span: Span, - substructure: &Substructure<'_>, + substructure: Substructure<'_>, ) -> BlockOrExpr { use SubstructureFields::*; @@ -148,7 +148,7 @@ fn get_substructure_equality_expr( .unwrap_or_else(|| cx.expr_bool(span, true)) } EnumDiscr(disc, match_expr) => { - let lhs = get_field_equality_expr(cx, disc); + let lhs = get_field_equality_expr(cx, &disc); let Some(match_expr) = match_expr else { return BlockOrExpr::new_expr(lhs); }; diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 0e547d441a74b..41b884b731a85 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -111,7 +111,7 @@ fn cs_partial_cmp_simple(cx: &ExtCtxt<'_>, span: Span, other_expr: Box, span: Span, - substr: &Substructure<'_>, + substr: Substructure<'_>, discr_then_data: bool, ) -> BlockOrExpr { let test_id = Ident::new(sym::cmp, span); From 49a77631a302b98782ebb0f1cbec60e2c6372d18 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 3 Sep 2026 12:24:03 +0000 Subject: [PATCH 14/19] less clones in `cs_clone` --- .../src/deriving/clone.rs | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index dff4785bd5fa0..38696790bd98c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -166,14 +166,14 @@ fn cs_clone_simple( } fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { - let ctor_path; - let all_fields; let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]); - let subcall = |cx: &ExtCtxt<'_>, field: &FieldInfo| { - let args = thin_vec![field.self_expr.clone()]; + let subcall = |field: FieldInfo| { + let args = thin_vec![field.self_expr]; cx.expr_call_global(field.span, fn_path.clone(), args) }; + let ctor_path; + let all_fields; let vdata; match substr.fields { Struct(vdata_, af) => { @@ -192,23 +192,14 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo let expr = match *vdata { VariantData::Struct { .. } => { let fields = all_fields - .iter() - .map(|field| { - let Some(ident) = field.name else { - cx.dcx().span_bug( - trait_span, - "unnamed field in normal struct in `derive(Clone)`", - ); - }; - let call = subcall(cx, field); - cx.field_imm(field.span, ident, call) - }) + .into_iter() + .map(|field| cx.field_imm(field.span, field.name.unwrap(), subcall(field))) .collect::>(); cx.expr_struct(trait_span, ctor_path, fields) } VariantData::Tuple(..) => { - let subcalls = all_fields.iter().map(|f| subcall(cx, f)).collect(); + let subcalls = all_fields.into_iter().map(subcall).collect(); let path = cx.expr_path(ctor_path); cx.expr_call(trait_span, path, subcalls) } From 3bc743c90d9d43945f4c2ad6110cfd487d621d9d Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 4 Sep 2026 08:22:36 +0000 Subject: [PATCH 15/19] avoid collecting into intermediate `Vec`s --- .../src/deriving/generic/mod.rs | 140 ++++++++---------- 1 file changed, 65 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index e8a269b8467d8..a7438bc0eb402 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -567,8 +567,8 @@ impl<'a> TraitDef<'a> { cx: &ExtCtxt<'_>, type_ident: Ident, generics: &Generics, - field_tys: Vec<&ast::Ty>, - methods: Vec>, + field_tys: impl Iterator, + methods: impl Iterator>, is_packed: bool, ) -> Box { let trait_path = self.path.to_path(cx, self.span, type_ident, generics); @@ -821,7 +821,7 @@ impl<'a> TraitDef<'a> { })), constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No }, self_ty: self_type, - items: methods.into_iter().chain(associated_types).collect(), + items: methods.chain(associated_types).collect(), }), ) } @@ -835,46 +835,42 @@ impl<'a> TraitDef<'a> { from_scratch: bool, is_packed: bool, ) -> Box { - let field_tys = Vec::from_iter(struct_def.fields().iter().map(|field| &*field.ty)); + let field_tys = struct_def.fields().iter().map(|field| &*field.ty); - let methods = self - .methods - .iter() - .map(|method_def| { - let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = - method_def.extract_arg_details(cx, self, type_ident, generics); + let methods = self.methods.iter().map(|method_def| { + let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = + method_def.extract_arg_details(cx, self, type_ident, generics); - let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method( - cx, - self, - type_ident, - &nonselflike_args, - StaticStruct(struct_def), - ) - } else { - method_def.expand_struct_method_body( - cx, - self, - struct_def, - type_ident, - &selflike_args, - &nonselflike_args, - is_packed, - ) - }; - - method_def.create_method( + let body = if from_scratch || method_def.is_static() { + method_def.call_substructure_method( cx, self, type_ident, - generics, - explicit_self, - nonself_arg_tys, - body, + &nonselflike_args, + StaticStruct(struct_def), ) - }) - .collect(); + } else { + method_def.expand_struct_method_body( + cx, + self, + struct_def, + type_ident, + &selflike_args, + &nonselflike_args, + is_packed, + ) + }; + + method_def.create_method( + cx, + self, + type_ident, + generics, + explicit_self, + nonself_arg_tys, + body, + ) + }); self.create_derived_impl(cx, type_ident, generics, field_tys, methods, is_packed) } @@ -887,51 +883,45 @@ impl<'a> TraitDef<'a> { generics: &Generics, from_scratch: bool, ) -> Box { - let field_tys = Vec::from_iter( - enum_def - .variants - .iter() - .flat_map(|variant| variant.data.fields()) - .map(|field| &*field.ty), - ); - - let methods = self - .methods + let field_tys = enum_def + .variants .iter() - .map(|method_def| { - let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = - method_def.extract_arg_details(cx, self, type_ident, generics); + .flat_map(|variant| variant.data.fields()) + .map(|field| &*field.ty); - let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method( - cx, - self, - type_ident, - &nonselflike_args, - StaticEnum(enum_def), - ) - } else { - method_def.expand_enum_method_body( - cx, - self, - enum_def, - type_ident, - selflike_args, - &nonselflike_args, - ) - }; + let methods = self.methods.iter().map(|method_def| { + let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = + method_def.extract_arg_details(cx, self, type_ident, generics); - method_def.create_method( + let body = if from_scratch || method_def.is_static() { + method_def.call_substructure_method( cx, self, type_ident, - generics, - explicit_self, - nonself_arg_tys, - body, + &nonselflike_args, + StaticEnum(enum_def), ) - }) - .collect(); + } else { + method_def.expand_enum_method_body( + cx, + self, + enum_def, + type_ident, + selflike_args, + &nonselflike_args, + ) + }; + + method_def.create_method( + cx, + self, + type_ident, + generics, + explicit_self, + nonself_arg_tys, + body, + ) + }); let is_packed = false; // enums are never packed self.create_derived_impl(cx, type_ident, generics, field_tys, methods, is_packed) From b3310a27296c48d44c7059611563fdac0cd8103d Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 4 Sep 2026 10:18:39 +0000 Subject: [PATCH 16/19] remove `Bounds` in favor of `ast::Generics` --- .../src/deriving/clone.rs | 2 +- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 2 +- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 4 +- .../src/deriving/generic/mod.rs | 6 +-- .../src/deriving/generic/ty.rs | 53 ------------------- .../rustc_builtin_macros/src/deriving/hash.rs | 18 +++++-- .../rustc_builtin_macros/src/deriving/ord.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- compiler/rustc_expand/src/build.rs | 12 +++++ 12 files changed, 39 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 38696790bd98c..6b5fb0df9e458 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -89,7 +89,7 @@ pub(crate) fn expand_deriving_clone( supports_unions: true, methods: smallvec![MethodDef { name: sym::clone, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: SmallVec::new(), ret_ty: Self_, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index ac409f2403d3e..f0e02fb5270d3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -28,7 +28,7 @@ pub(crate) fn expand_deriving_debug( supports_unions: false, methods: smallvec![MethodDef { name: sym::fmt, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: smallvec![(fmtr, sym::character('f'))], ret_ty: Path(path_std!(fmt::Result)), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index ca0bf631110b8..05872e73fad75 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_default( supports_unions: false, methods: smallvec![MethodDef { name: kw::Default, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: false, nonself_args: SmallVec::new(), ret_ty: Self_, diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index d651a84bb0155..672efcadafc0c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -27,7 +27,7 @@ pub(crate) fn expand_deriving_eq( supports_unions: true, methods: smallvec![MethodDef { name: sym::assert_fields_are_eq, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: smallvec![], ret_ty: Unit, diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index eb8ddd10d4306..188f3a4b92b91 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -5,7 +5,7 @@ use rustc_expand::base::{DummyResult, ExtCtxt}; use rustc_span::{Ident, Span, kw, sym}; use thin_vec::thin_vec; -use crate::deriving::generic::ty::{Bounds, Path, PathKind, Ty}; +use crate::deriving::generic::ty::{Path, PathKind, Ty}; use crate::deriving::generic::*; use crate::deriving::pathvec; use crate::diagnostics; @@ -75,7 +75,7 @@ pub(crate) fn expand_deriving_from( supports_unions: false, methods: smallvec![MethodDef { name: sym::from, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: false, nonself_args: smallvec![(from_type, sym::value)], ret_ty: Ty::Self_, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index a7438bc0eb402..cd7aa90891fe6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -191,7 +191,7 @@ use rustc_expand::base::ExtCtxt; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, respan, sym}; pub(crate) use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; -use ty::{Bounds, Path, Ref, Self_, Ty}; +use ty::{Path, Ref, Self_, Ty}; use crate::{deriving, diagnostics}; @@ -234,7 +234,7 @@ pub(crate) struct MethodDef<'a> { /// name of the method pub name: Symbol, /// List of generics, e.g., `R: rand::Rng` - pub generics: Bounds, + pub generics: Generics, /// Is there is a `&self` argument? If not, it is a static function. pub explicit_self: bool, @@ -1007,7 +1007,7 @@ impl<'a> MethodDef<'a> { ) -> Box { let span = trait_.span; // Create the generics that aren't for `Self`. - let fn_generics = self.generics.to_generics(cx, span, type_ident, generics); + let fn_generics = self.generics.clone(); let args = { let self_arg = explicit_self.map(|explicit_self| { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 6e504534ba26d..98ad5b8faf52b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -131,56 +131,3 @@ impl Ty { } } } - -fn mk_ty_param( - cx: &ExtCtxt<'_>, - span: Span, - name: Symbol, - bounds: &[Path], - self_ident: Ident, - self_generics: &Generics, -) -> ast::GenericParam { - let bounds = bounds - .iter() - .map(|b| { - let path = b.to_path(cx, span, self_ident, self_generics); - cx.trait_bound(path, false) - }) - .collect(); - cx.typaram(span, Ident::new(name, span), bounds, None) -} - -/// Bounds on type parameters. -#[derive(Clone)] -pub(crate) struct Bounds { - pub bounds: Vec<(Symbol, Vec)>, -} - -impl Bounds { - pub(crate) fn empty() -> Bounds { - Bounds { bounds: Vec::new() } - } - pub(crate) fn to_generics( - &self, - cx: &ExtCtxt<'_>, - span: Span, - self_ty: Ident, - self_generics: &Generics, - ) -> Generics { - let params = self - .bounds - .iter() - .map(|&(name, ref bounds)| mk_ty_param(cx, span, name, bounds, self_ty, self_generics)) - .collect(); - - Generics { - params, - where_clause: ast::WhereClause { - has_where_token: false, - predicates: ThinVec::new(), - span, - }, - span, - } - } -} diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index b87fbf88fe8b7..22a8d8b10a9c2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,7 +1,7 @@ use rustc_ast::{MetaItem, Mutability, Safety}; use rustc_expand::base::ExtCtxt; -use rustc_span::{Span, sym}; -use thin_vec::thin_vec; +use rustc_span::{Ident, Span, sym}; +use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::ty::*; use crate::deriving::generic::*; @@ -20,6 +20,18 @@ pub(crate) fn expand_deriving_hash( let typaram = sym::__H; let arg = Path::new_local(typaram); + + let param = { + let path = cx.path_all(span, false, cx.std_path(&[sym::hash, sym::Hasher]), Vec::new()); + cx.typaram(span, Ident::new(typaram, span), thin_vec![cx.trait_bound(path, false)], None) + }; + + let generics = ast::Generics { + params: thin_vec![param], + where_clause: ast::WhereClause { has_where_token: false, predicates: ThinVec::new(), span }, + span, + }; + let hash_trait_def = TraitDef { span, path, @@ -29,7 +41,7 @@ pub(crate) fn expand_deriving_hash( supports_unions: false, methods: smallvec![MethodDef { name: sym::hash, - generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] }, + generics, explicit_self: true, nonself_args: smallvec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)], ret_ty: Unit, diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index 4d3084a87db43..91849c9c6a19e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -24,7 +24,7 @@ pub(crate) fn expand_deriving_ord( supports_unions: false, methods: smallvec![MethodDef { name: sym::cmp, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: smallvec![(self_ref(), sym::other)], ret_ty: Path(path_std!(cmp::Ordering)), diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 76fedf84adc09..15267ebc3b973 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -41,7 +41,7 @@ pub(crate) fn expand_deriving_partial_eq( // faster. let methods = smallvec![MethodDef { name: sym::eq, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: smallvec![(self_ref(), sym::other)], ret_ty: Path(generic::ty::Path::new_local(sym::bool)), diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 41b884b731a85..eede37bfecc5e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -72,7 +72,7 @@ pub(crate) fn expand_deriving_partial_ord( let partial_cmp_def = MethodDef { name: sym::partial_cmp, - generics: Bounds::empty(), + generics: cx.empty_generics(span), explicit_self: true, nonself_args: smallvec![(self_ref(), sym::other)], ret_ty, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 2240fe115fde3..393acc7e2e65f 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -767,4 +767,16 @@ impl<'a> ExtCtxt<'a> { let g = &self.sess.psess.attr_id_generator; attr::mk_attr_from_item(g, inner, None, ast::AttrStyle::Outer, span) } + + pub fn empty_generics(&self, span: Span) -> ast::Generics { + ast::Generics { + params: ThinVec::new(), + where_clause: ast::WhereClause { + has_where_token: false, + predicates: ThinVec::new(), + span, + }, + span, + } + } } From 785ad11a8a5412214de82af260d01aa4026a86c4 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 4 Sep 2026 11:08:56 +0000 Subject: [PATCH 17/19] avoid emitting empty `assert_fields_are_equal` methods --- .../src/deriving/generic/mod.rs | 12 ++++++++--- tests/ui/derives/deriving-all-codegen.stdout | 21 +++---------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index cd7aa90891fe6..8a581b10189a2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -889,7 +889,7 @@ impl<'a> TraitDef<'a> { .flat_map(|variant| variant.data.fields()) .map(|field| &*field.ty); - let methods = self.methods.iter().map(|method_def| { + let methods = self.methods.iter().filter_map(|method_def| { let ArgDetails { explicit_self, selflike_args, nonselflike_args, nonself_arg_tys } = method_def.extract_arg_details(cx, self, type_ident, generics); @@ -912,7 +912,13 @@ impl<'a> TraitDef<'a> { ) }; - method_def.create_method( + // `assert_fields_are_eq` has an empty default implementation + if body.0.is_empty() && body.1.is_none() && method_def.name == sym::assert_fields_are_eq + { + return None; + } + + Some(method_def.create_method( cx, self, type_ident, @@ -920,7 +926,7 @@ impl<'a> TraitDef<'a> { explicit_self, nonself_arg_tys, body, - ) + )) }); let is_packed = false; // enums are never packed diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 54b1976207236..436f57bb8ecb9 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -1009,12 +1009,7 @@ impl ::core::cmp::PartialEq for Enum0 { fn eq(&self, other: &Enum0) -> bool { match *self {} } } #[automatically_derived] -impl ::core::cmp::Eq for Enum0 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_fields_are_eq(&self) {} -} +impl ::core::cmp::Eq for Enum0 { } #[automatically_derived] impl ::core::cmp::PartialOrd for Enum0 { #[inline] @@ -1142,12 +1137,7 @@ impl ::core::cmp::PartialEq for Fieldless1 { fn eq(&self, other: &Fieldless1) -> bool { true } } #[automatically_derived] -impl ::core::cmp::Eq for Fieldless1 { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_fields_are_eq(&self) {} -} +impl ::core::cmp::Eq for Fieldless1 { } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless1 { #[inline] @@ -1219,12 +1209,7 @@ impl ::core::cmp::PartialEq for Fieldless { } } #[automatically_derived] -impl ::core::cmp::Eq for Fieldless { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_fields_are_eq(&self) {} -} +impl ::core::cmp::Eq for Fieldless { } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless { #[inline] From 68db54ec43f6d9525f0d7a6ee24a932c5ccbcdd1 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 4 Sep 2026 21:11:07 +0000 Subject: [PATCH 18/19] utilize `cx.pat_ident` --- .../src/deriving/generic/mod.rs | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 8a581b10189a2..063a29f2758c0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -182,8 +182,8 @@ pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentIsRaw, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; use rustc_ast::{ - AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg, GenericParamKind, Generics, - Mutability, PatKind, Safety, SelfKind, VariantData, + AttrArgs, DelimArgs, EnumDef, Expr, GenericArg, GenericParamKind, Generics, Safety, SelfKind, + VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; use rustc_attr_parsing::AttributeParser; @@ -1289,14 +1289,8 @@ impl<'a> MethodDef<'a> { let sp = variant.span.with_ctxt(trait_.span.ctxt()); let variant_path = cx.path(sp, vec![type_ident, variant.ident]); - let by_ref = ByRef::No; // because enums can't be repr(packed) - let mut subpats = trait_.create_struct_patterns( - cx, - variant_path, - &variant.data, - &prefixes, - by_ref, - ); + let mut subpats = + trait_.create_struct_patterns(cx, variant_path, &variant.data, &prefixes); // `(VariantK, VariantK, ...)` or just `VariantK`. let single_pat = if subpats.len() == 1 { @@ -1405,7 +1399,6 @@ impl<'a> TraitDef<'a> { struct_path: ast::Path, struct_def: &'a VariantData, prefixes: &[String], - by_ref: ByRef, ) -> ThinVec { prefixes .iter() @@ -1415,13 +1408,7 @@ impl<'a> TraitDef<'a> { let sp = struct_field.span.with_ctxt(self.span.ctxt()); let ident = self.mk_pattern_ident(prefix, i); let path = ident.with_span_pos(sp); - ( - struct_field.ident, - cx.pat( - path.span, - PatKind::Ident(BindingMode(by_ref, Mutability::Not), path, None), - ), - ) + (struct_field.ident, cx.pat_ident(path.span, path)) }); let struct_path = struct_path.clone(); From dc2a811be8c571d34171f0a8fd2ec4b4244a1b99 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 4 Sep 2026 21:18:26 +0000 Subject: [PATCH 19/19] stop passing a `&MetaItem` around --- compiler/rustc_builtin_macros/src/deriving/clone.rs | 7 +++---- .../rustc_builtin_macros/src/deriving/coerce_pointee.rs | 3 +-- .../rustc_builtin_macros/src/deriving/const_param_ty.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/copy.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/debug.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/default.rs | 3 +-- compiler/rustc_builtin_macros/src/deriving/eq.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/from.rs | 3 +-- compiler/rustc_builtin_macros/src/deriving/generic/mod.rs | 6 ++---- compiler/rustc_builtin_macros/src/deriving/hash.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/mod.rs | 6 ++---- compiler/rustc_builtin_macros/src/deriving/ord.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/partial_eq.rs | 7 +++---- compiler/rustc_builtin_macros/src/deriving/partial_ord.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/reborrow.rs | 6 +----- 15 files changed, 28 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 6b5fb0df9e458..3257fc3437273 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, Safety, VariantData}; +use rustc_ast::{self as ast, Generics, ItemKind, Safety, VariantData}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::ExtCtxt; use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; @@ -11,7 +11,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_clone( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -77,7 +76,7 @@ pub(crate) fn expand_deriving_clone( document: false, }; - trivial_def.expand(cx, mitem, item, push); + trivial_def.expand(cx, item, push); } let trait_def = TraitDef { @@ -103,7 +102,7 @@ pub(crate) fn expand_deriving_clone( document: true, }; - trait_def.expand_ext(cx, mitem, item, push, is_simple) + trait_def.expand_ext(cx, item, push, is_simple) } fn cs_clone_simple( diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index ced806a139ed7..ab9037331050e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -2,7 +2,7 @@ use ast::HasAttrs; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::visit::{BoundKind, Visitor}; use rustc_ast::{ - self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, MetaItem, + self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, TraitBoundModifiers, VariantData, WherePredicate, }; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; @@ -21,7 +21,6 @@ macro_rules! path { pub(crate) fn expand_deriving_coerce_pointee( cx: &ExtCtxt<'_>, span: Span, - _mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), _is_const: bool, diff --git a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs index 18a9df86b547e..8034a3e9b0b16 100644 --- a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItem, Safety}; +use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; @@ -8,7 +8,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_const_param_ty( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -27,5 +26,5 @@ pub(crate) fn expand_deriving_const_param_ty( document: true, }; - trait_def.expand(cx, mitem, item, push); + trait_def.expand(cx, item, push); } diff --git a/compiler/rustc_builtin_macros/src/deriving/copy.rs b/compiler/rustc_builtin_macros/src/deriving/copy.rs index 5743d27cf7458..bae4bd98df465 100644 --- a/compiler/rustc_builtin_macros/src/deriving/copy.rs +++ b/compiler/rustc_builtin_macros/src/deriving/copy.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItem, Safety}; +use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; @@ -8,7 +8,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_copy( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -27,5 +26,5 @@ pub(crate) fn expand_deriving_copy( document: true, }; - trait_def.expand(cx, mitem, item, push); + trait_def.expand(cx, item, push); } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index f0e02fb5270d3..e694502d607e8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, EnumDef, MetaItem, Safety}; +use rustc_ast::{self as ast, EnumDef, Safety}; use rustc_expand::base::ExtCtxt; use rustc_session::config::FmtDebug; use rustc_span::{Ident, Span, Symbol, sym}; @@ -11,7 +11,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_debug( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -42,7 +41,7 @@ pub(crate) fn expand_deriving_debug( safety: Safety::Default, document: true, }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, item, push) } fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 05872e73fad75..f9f9af4e9f012 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -14,7 +14,6 @@ use crate::diagnostics; pub(crate) fn expand_deriving_default( cx: &ExtCtxt<'_>, span: Span, - mitem: &ast::MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -55,7 +54,7 @@ pub(crate) fn expand_deriving_default( safety: Safety::Default, document: true, }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, item, push) } fn default_call(cx: &ExtCtxt<'_>, span: Span) -> Box { diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index 672efcadafc0c..eaf9298fc10c7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, MetaItem, Safety}; +use rustc_ast::{self as ast, Safety}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; @@ -11,7 +11,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_eq( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -46,7 +45,7 @@ pub(crate) fn expand_deriving_eq( safety: Safety::Default, document: true, }; - trait_def.expand_ext(cx, mitem, item, push, true) + trait_def.expand_ext(cx, item, push, true) } fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 188f3a4b92b91..0b28df9850097 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -15,7 +15,6 @@ use crate::diagnostics; pub(crate) fn expand_deriving_from( cx: &ExtCtxt<'_>, span: Span, - mitem: &ast::MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -123,5 +122,5 @@ pub(crate) fn expand_deriving_from( document: true, }; - from_trait_def.expand(cx, mitem, item, push); + from_trait_def.expand(cx, item, push); } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 063a29f2758c0..72c3252f7854e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -458,17 +458,15 @@ impl<'a> TraitDef<'a> { pub(crate) fn expand( self, cx: &ExtCtxt<'_>, - mitem: &ast::MetaItem, item: &'a ast::Item, push: &mut dyn FnMut(Box), ) { - self.expand_ext(cx, mitem, item, push, false); + self.expand_ext(cx, item, push, false); } pub(crate) fn expand_ext( self, cx: &ExtCtxt<'_>, - mitem: &ast::MetaItem, item: &'a ast::Item, push: &mut dyn FnMut(Box), from_scratch: bool, @@ -501,7 +499,7 @@ impl<'a> TraitDef<'a> { is_packed, ) } else { - cx.dcx().emit_err(diagnostics::DeriveUnion { span: mitem.span }); + cx.dcx().emit_err(diagnostics::DeriveUnion { span: self.span }); return; } } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 22a8d8b10a9c2..b6a87851254fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItem, Mutability, Safety}; +use rustc_ast::{Mutability, Safety}; use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -10,7 +10,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_hash( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -55,7 +54,7 @@ pub(crate) fn expand_deriving_hash( document: true, }; - hash_trait_def.expand(cx, mitem, item, push); + hash_trait_def.expand(cx, item, push); } fn hash_substructure(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 404991903c424..a1b1d56664f22 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -31,7 +31,7 @@ pub(crate) mod reborrow; pub(crate) mod generic; pub(crate) type BuiltinDeriveFn = - fn(&ExtCtxt<'_>, Span, &MetaItem, &ast::Item, &mut dyn FnMut(Box), bool); + fn(&ExtCtxt<'_>, Span, &ast::Item, &mut dyn FnMut(Box), bool); pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn); @@ -40,7 +40,7 @@ impl MultiItemModifier for BuiltinDerive { &self, ecx: &mut ExtCtxt<'_>, span: Span, - meta_item: &MetaItem, + _: &MetaItem, item: Annotatable, is_derive_const: bool, ) -> ExpandResult, Annotatable> { @@ -54,7 +54,6 @@ impl MultiItemModifier for BuiltinDerive { (self.0)( ecx, span, - meta_item, &item, &mut |a| items.push(Annotatable::Stmt(Box::new(ecx.stmt_item(span, a)))), is_derive_const, @@ -66,7 +65,6 @@ impl MultiItemModifier for BuiltinDerive { Annotatable::Item(item) => (self.0)( ecx, span, - meta_item, &item, &mut |a| items.push(Annotatable::Item(a)), is_derive_const, diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index 91849c9c6a19e..3c2d95a299a51 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItem, Safety}; +use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -10,7 +10,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_ord( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -38,7 +37,7 @@ pub(crate) fn expand_deriving_ord( document: true, }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, item, push) } pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 15267ebc3b973..be48c0532e596 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -1,4 +1,4 @@ -use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability, Safety}; +use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, Mutability, Safety}; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -12,7 +12,6 @@ use crate::deriving::path_std; pub(crate) fn expand_deriving_partial_eq( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -35,7 +34,7 @@ pub(crate) fn expand_deriving_partial_eq( safety: Safety::Default, document: true, }; - structural_trait_def.expand(cx, mitem, item, push); + structural_trait_def.expand(cx, item, push); // No need to generate `ne`, the default suffices, and not generating it is // faster. @@ -63,7 +62,7 @@ pub(crate) fn expand_deriving_partial_eq( safety: Safety::Default, document: true, }; - trait_def.expand(cx, mitem, item, push) + trait_def.expand(cx, item, push) } /// Generates the equality expression for a struct or enum variant when deriving diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index eede37bfecc5e..fe5e48b11367d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety, ast}; +use rustc_ast::{ExprKind, ItemKind, PatKind, Safety, ast}; use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, sym}; use thin_vec::thin_vec; @@ -10,7 +10,6 @@ use crate::deriving::{path_std, pathvec}; pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, span: Span, - mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), is_const: bool, @@ -94,7 +93,7 @@ pub(crate) fn expand_deriving_partial_ord( safety: Safety::Default, document: true, }; - trait_def.expand_ext(cx, mitem, item, push, is_simple) + trait_def.expand_ext(cx, item, push, is_simple) } // Special case for the type deriving both `PartialOrd` and `Ord`. Builds: diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index 43d24417acc00..dc45b1a896bc9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -1,6 +1,4 @@ -use rustc_ast::{ - self as ast, AttrArgs, GenericArg, GenericParamKind, Generics, ItemKind, MetaItem, token, -}; +use rustc_ast::{self as ast, AttrArgs, GenericArg, GenericParamKind, Generics, ItemKind, token}; use rustc_errors::E0802; use rustc_expand::base::ExtCtxt; use rustc_macros::Diagnostic; @@ -14,7 +12,6 @@ macro_rules! path { pub(crate) fn expand_deriving_reborrow( cx: &ExtCtxt<'_>, span: Span, - _mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), _is_const: bool, @@ -29,7 +26,6 @@ pub(crate) fn expand_deriving_reborrow( pub(crate) fn expand_deriving_coerce_shared( cx: &ExtCtxt<'_>, span: Span, - _mitem: &MetaItem, item: &ast::Item, push: &mut dyn FnMut(Box), _is_const: bool,