diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index f072b4b9e5cd1..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, @@ -55,7 +54,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 @@ -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 { @@ -89,7 +88,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_, @@ -103,13 +102,13 @@ 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( cx: &ExtCtxt<'_>, trait_span: Span, - substr: &Substructure<'_>, + substr: Substructure<'_>, is_union: bool, ) -> BlockOrExpr { let mut stmts = ThinVec::new(); @@ -150,7 +149,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match *substr.fields { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -165,55 +164,41 @@ 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 { - let ctor_path; - let all_fields; +fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { 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) => { 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]); 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 { 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) } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 58b4734b132c3..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, @@ -320,7 +319,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 { @@ -328,10 +327,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/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 3c80c01aa32b0..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, @@ -28,7 +27,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)), @@ -42,10 +41,10 @@ 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 { +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,12 +54,10 @@ 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), - 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); @@ -88,20 +85,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 +118,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 +134,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); } @@ -224,7 +216,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 9e65ae0b75cab..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, @@ -30,7 +29,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_, @@ -44,7 +43,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)`"), } }), }], @@ -53,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 { @@ -65,7 +66,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..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, @@ -27,7 +26,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, @@ -46,14 +45,10 @@ 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 { +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 +73,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/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index eb8ddd10d4306..0b28df9850097 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; @@ -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, @@ -75,7 +74,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_, @@ -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 3298b4a583ff8..d69f9ab7f0641 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; @@ -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, @@ -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) } @@ -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; } } @@ -567,8 +565,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 +819,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 +833,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 (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, - ) - }; + 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, + 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,57 +881,69 @@ 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 (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.expand_static_enum_method_body( - cx, - self, - enum_def, - type_ident, - &nonselflike_args, - ) - } else { - method_def.expand_enum_method_body( - cx, - self, - enum_def, - type_ident, - selflike_args, - &nonselflike_args, - ) - }; + 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); - 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, + ) + }; + + // `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, + 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) } } +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, @@ -945,33 +951,25 @@ 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 { !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 +996,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( @@ -1013,7 +1011,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| { @@ -1114,7 +1112,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &Struct(struct_def, selflike_fields), + Struct(struct_def, selflike_fields), ) } @@ -1244,7 +1242,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); @@ -1255,7 +1253,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &AllFieldlessEnum(enum_def), + AllFieldlessEnum(enum_def), ); } FieldlessVariantsStrategy::Default => (), @@ -1268,7 +1266,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumMatching(variant, Vec::new()), + EnumMatching(variant, Vec::new()), ); } } @@ -1289,14 +1287,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 { @@ -1320,7 +1312,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &substructure, + substructure, ) .into_expr(cx, span); @@ -1341,7 +1333,7 @@ impl<'a> MethodDef<'a> { trait_, type_ident, nonselflike_args, - &EnumMatching(v, Vec::new()), + EnumMatching(v, Vec::new()), ) .into_expr(cx, span), ) @@ -1387,7 +1379,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) @@ -1395,23 +1387,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. @@ -1422,7 +1397,6 @@ impl<'a> TraitDef<'a> { struct_path: ast::Path, struct_def: &'a VariantData, prefixes: &[String], - by_ref: ByRef, ) -> ThinVec { prefixes .iter() @@ -1432,42 +1406,28 @@ 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); - ( - 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(); 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), @@ -1564,10 +1524,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 ` && `. @@ -1583,52 +1543,44 @@ 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) => { - if all_fields.is_empty() { - return f(cx, CsFold::Fieldless); - } + let mut fields = all_fields.into_iter(); - let (base_field, rest) = if use_foldl { - all_fields.split_first().unwrap() - } else { - all_fields.split_last().unwrap() + let base_field = if use_foldl { fields.next() } else { fields.next_back() }; + + let Some(base_field) = base_field else { + return f(cx, CsFold::Fieldless); }; 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) - } else { - rest.iter().rfold(base_expr, op) - } + if use_foldl { fields.fold(base_expr, op) } else { fields.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 } } - 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/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 6864b05ae08cd..b6a87851254fc 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_ast::{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::*; @@ -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, @@ -20,6 +19,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 +40,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, @@ -43,10 +54,10 @@ 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 { +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,15 +71,15 @@ 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, "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/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 fb8d425841722..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, @@ -24,7 +23,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)), @@ -38,10 +37,10 @@ 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 { +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 a65962bfc9731..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,13 +34,13 @@ 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. 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)), @@ -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 @@ -120,7 +119,7 @@ pub(crate) fn expand_deriving_partial_eq( fn get_substructure_equality_expr( cx: &ExtCtxt<'_>, span: Span, - substructure: &Substructure<'_>, + substructure: Substructure<'_>, ) -> BlockOrExpr { use SubstructureFields::*; @@ -141,13 +140,14 @@ 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)) } 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); }; @@ -155,18 +155,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)`"), }) } diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 0e547d441a74b..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, @@ -72,7 +71,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, @@ -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: @@ -111,7 +110,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); 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, 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, + } + } } 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]