From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_builtin_macros/src/deriving/bounds.rs | 4 +- .../rustc_builtin_macros/src/deriving/clone.rs | 22 +- .../rustc_builtin_macros/src/deriving/cmp/eq.rs | 15 +- .../rustc_builtin_macros/src/deriving/cmp/ord.rs | 6 +- .../src/deriving/cmp/partial_eq.rs | 6 +- .../src/deriving/cmp/partial_ord.rs | 6 +- .../rustc_builtin_macros/src/deriving/debug.rs | 3 +- .../rustc_builtin_macros/src/deriving/decodable.rs | 23 ++- .../rustc_builtin_macros/src/deriving/default.rs | 21 +- .../rustc_builtin_macros/src/deriving/encodable.rs | 11 +- .../src/deriving/generic/mod.rs | 225 ++++++++------------- .../src/deriving/generic/ty.rs | 9 +- compiler/rustc_builtin_macros/src/deriving/hash.rs | 3 +- compiler/rustc_builtin_macros/src/deriving/mod.rs | 43 ++-- 14 files changed, 176 insertions(+), 221 deletions(-) (limited to 'compiler/rustc_builtin_macros/src/deriving') diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 7bd344467..240167146 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -1,4 +1,3 @@ -use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; @@ -12,16 +11,17 @@ pub fn expand_deriving_copy( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let trait_def = TraitDef { span, path: path_std!(marker::Copy), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: true, methods: Vec::new(), associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index fa8685f5f..d59b3b8c8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -14,6 +14,7 @@ pub fn expand_deriving_clone( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { // The simple form is `fn clone(&self) -> Self { *self }`, possibly with // some additional `AssertParamIsClone` assertions. @@ -31,10 +32,10 @@ pub fn expand_deriving_clone( let bounds; let substructure; let is_simple; - match *item { - Annotatable::Item(ref annitem) => match annitem.kind { - ItemKind::Struct(_, Generics { ref params, .. }) - | ItemKind::Enum(_, Generics { ref params, .. }) => { + 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); if has_derive_copy @@ -67,14 +68,12 @@ pub fn expand_deriving_clone( _ => cx.span_bug(span, "`#[derive(Clone)]` on trait item or impl item"), } - let inline = cx.meta_word(span, sym::inline); - let attrs = thin_vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attr_word(sym::inline, span)]; let trait_def = TraitDef { span, path: path_std!(clone::Clone), skip_path_as_bound: false, additional_bounds: bounds, - generics: Bounds::empty(), supports_unions: true, methods: vec![MethodDef { name: sym::clone, @@ -87,6 +86,7 @@ pub fn expand_deriving_clone( combine_substructure: substructure, }], associated_types: Vec::new(), + is_const, }; trait_def.expand_ext(cx, mitem, item, push, is_simple) @@ -166,13 +166,13 @@ fn cs_clone( }; let vdata; - match *substr.fields { - Struct(vdata_, ref af) => { + 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, ref af) => { + EnumMatching(.., variant, af) => { ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); all_fields = af; vdata = &variant.data; diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index eab67b0d3..f861d47ed 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -5,7 +5,7 @@ use crate::deriving::path_std; use rustc_ast::{self as ast, MetaItem}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::sym; use rustc_span::Span; use thin_vec::thin_vec; @@ -15,19 +15,19 @@ pub fn expand_deriving_eq( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let span = cx.with_def_site_ctxt(span); - let inline = cx.meta_word(span, sym::inline); - let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span)); - let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]); - let no_coverage = cx.meta_word(span, sym::no_coverage); - let attrs = thin_vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; + let attrs = thin_vec![ + cx.attr_word(sym::inline, span), + cx.attr_nested_word(sym::doc, sym::hidden, span), + cx.attr_word(sym::no_coverage, span) + ]; let trait_def = TraitDef { span, path: path_std!(cmp::Eq), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: true, methods: vec![MethodDef { name: sym::assert_receiver_is_total_eq, @@ -42,6 +42,7 @@ pub fn expand_deriving_eq( })), }], associated_types: Vec::new(), + is_const, }; super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push); diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 7f117981a..96d18c7af 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -13,15 +13,14 @@ pub fn expand_deriving_ord( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { - let inline = cx.meta_word(span, sym::inline); - let attrs = thin_vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attr_word(sym::inline, span)]; let trait_def = TraitDef { span, path: path_std!(cmp::Ord), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: sym::cmp, @@ -34,6 +33,7 @@ pub fn expand_deriving_ord( combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) 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 236cbccaf..7f95551fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { let base = true; @@ -67,8 +68,7 @@ pub fn expand_deriving_partial_eq( // No need to generate `ne`, the default suffices, and not generating it is // faster. - let inline = cx.meta_word(span, sym::inline); - let attrs = thin_vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attr_word(sym::inline, span)]; let methods = vec![MethodDef { name: sym::eq, generics: Bounds::empty(), @@ -85,10 +85,10 @@ pub fn expand_deriving_partial_eq( path: path_std!(cmp::PartialEq), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods, associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } 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 4173403a1..5c4e5b7f8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -13,13 +13,13 @@ pub fn expand_deriving_partial_ord( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let ordering_ty = Path(path_std!(cmp::Ordering)); let ret_ty = Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std)); - let inline = cx.meta_word(span, sym::inline); - let attrs = thin_vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attr_word(sym::inline, span)]; let partial_cmp_def = MethodDef { name: sym::partial_cmp, @@ -39,10 +39,10 @@ pub fn expand_deriving_partial_ord( path: path_std!(cmp::PartialOrd), skip_path_as_bound: false, additional_bounds: vec![], - generics: Bounds::empty(), supports_unions: false, methods: vec![partial_cmp_def], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 2cf614ed9..544d971b2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_debug( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { // &mut ::std::fmt::Formatter let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut); @@ -22,7 +23,6 @@ pub fn expand_deriving_debug( path: path_std!(fmt::Debug), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: sym::fmt, @@ -37,6 +37,7 @@ pub fn expand_deriving_debug( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index d669f6168..62af02c2b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let krate = sym::rustc_serialize; let typaram = sym::__D; @@ -25,7 +26,6 @@ pub fn expand_deriving_rustc_decodable( path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: sym::decode, @@ -55,6 +55,7 @@ pub fn expand_deriving_rustc_decodable( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) @@ -77,11 +78,11 @@ fn decodable_substructure( let blkarg = Ident::new(sym::_d, trait_span); let blkdecoder = cx.expr_ident(trait_span, blkarg); - let expr = match *substr.fields { - StaticStruct(_, ref summary) => { - let nfields = match *summary { - Unnamed(ref fields, _) => fields.len(), - Named(ref fields) => fields.len(), + let expr = match substr.fields { + StaticStruct(_, summary) => { + let nfields = match summary { + Unnamed(fields, _) => fields.len(), + Named(fields) => fields.len(), }; let fn_read_struct_field_path: Vec<_> = cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_struct_field]); @@ -118,7 +119,7 @@ fn decodable_substructure( ], ) } - StaticEnum(_, ref fields) => { + StaticEnum(_, fields) => { let variant = Ident::new(sym::i, trait_span); let mut arms = Vec::with_capacity(fields.len() + 1); @@ -193,10 +194,10 @@ fn decode_static_fields( where F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P, { - match *fields { - Unnamed(ref fields, is_tuple) => { + match fields { + Unnamed(fields, is_tuple) => { let path_expr = cx.expr_path(outer_pat_path); - if !is_tuple { + if !*is_tuple { path_expr } else { let fields = fields @@ -208,7 +209,7 @@ where cx.expr_call(trait_span, path_expr, fields) } } - Named(ref fields) => { + Named(fields) => { // use the field's span to get nicer error messages. let fields = fields .iter() diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 17df9fb27..eb66c4a69 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -16,17 +16,16 @@ pub fn expand_deriving_default( mitem: &ast::MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); - let inline = cx.meta_word(span, sym::inline); - let attrs = thin_vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attr_word(sym::inline, span)]; let trait_def = TraitDef { span, path: Path::new(vec![kw::Default, sym::Default]), skip_path_as_bound: has_a_default_variant(item), additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: kw::Default, @@ -47,6 +46,7 @@ pub fn expand_deriving_default( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } @@ -62,15 +62,12 @@ fn default_struct_substructure( let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new()); let expr = match summary { - Unnamed(ref fields, is_tuple) => { - if !is_tuple { - cx.expr_ident(trait_span, substr.type_ident) - } else { - let exprs = fields.iter().map(|sp| default_call(*sp)).collect(); - cx.expr_call_ident(trait_span, substr.type_ident, exprs) - } + Unnamed(_, false) => cx.expr_ident(trait_span, substr.type_ident), + Unnamed(fields, true) => { + let exprs = fields.iter().map(|sp| default_call(*sp)).collect(); + cx.expr_call_ident(trait_span, substr.type_ident, exprs) } - Named(ref fields) => { + Named(fields) => { let default_fields = fields .iter() .map(|&(ident, span)| cx.field_imm(span, ident, default_call(span))) @@ -145,7 +142,7 @@ fn extract_default_variant<'a>( let suggestion = default_variants .iter() .filter_map(|v| { - if v.ident == variant.ident { + if v.span == variant.span { None } else { Some((cx.sess.find_by_name(&v.attrs, kw::Default)?.span, String::new())) diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index f83f58b97..68bc0ff2e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let krate = sym::rustc_serialize; let typaram = sym::__S; @@ -109,7 +110,6 @@ pub fn expand_deriving_rustc_encodable( path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: sym::encode, @@ -139,6 +139,7 @@ pub fn expand_deriving_rustc_encodable( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) @@ -163,8 +164,8 @@ fn encodable_substructure( ], )); - match *substr.fields { - Struct(_, ref fields) => { + match substr.fields { + Struct(_, fields) => { let fn_emit_struct_field_path = cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]); let mut stmts = Vec::new(); @@ -223,7 +224,7 @@ fn encodable_substructure( BlockOrExpr::new_expr(expr) } - EnumMatching(idx, _, variant, ref fields) => { + EnumMatching(idx, _, variant, fields) => { // We're not generating an AST that the borrow checker is expecting, // so we need to generate a unique local variable to take the // mutable loan out on, otherwise we get conflicts which don't @@ -273,7 +274,7 @@ fn encodable_substructure( vec![ blkencoder, name, - cx.expr_usize(trait_span, idx), + cx.expr_usize(trait_span, *idx), cx.expr_usize(trait_span, fields.len()), blk, ], diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 16ee3aa89..beac591bf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData}; use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use std::cell::RefCell; use std::iter; use std::ops::Not; @@ -195,15 +195,14 @@ pub struct TraitDef<'a> { /// other than the current trait pub additional_bounds: Vec, - /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder` - pub generics: Bounds, - /// Can this trait be derived for unions? pub supports_unions: bool, pub methods: Vec>, pub associated_types: Vec<(Ident, Ty)>, + + pub is_const: bool, } pub struct MethodDef<'a> { @@ -301,12 +300,12 @@ struct TypeParameter { ty: P, } -// The code snippets built up for derived code are sometimes used as blocks -// (e.g. in a function body) and sometimes used as expressions (e.g. in a match -// arm). This structure avoids committing to either form until necessary, -// avoiding the insertion of any unnecessary blocks. -// -// The statements come before the expression. +/// The code snippets built up for derived code are sometimes used as blocks +/// (e.g. in a function body) and sometimes used as expressions (e.g. in a match +/// arm). This structure avoids committing to either form until necessary, +/// avoiding the insertion of any unnecessary blocks. +/// +/// The statements come before the expression. pub struct BlockOrExpr(Vec, Option>); impl BlockOrExpr { @@ -370,15 +369,14 @@ fn find_type_parameters( impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> { fn visit_ty(&mut self, ty: &'a ast::Ty) { - if let ast::TyKind::Path(_, ref path) = ty.kind { - if let Some(segment) = path.segments.first() { - if self.ty_param_names.contains(&segment.ident.name) { - self.type_params.push(TypeParameter { - bound_generic_params: self.bound_generic_params_stack.clone(), - ty: P(ty.clone()), - }); - } - } + if let ast::TyKind::Path(_, path) = &ty.kind + && let Some(segment) = path.segments.first() + && self.ty_param_names.contains(&segment.ident.name) + { + self.type_params.push(TypeParameter { + bound_generic_params: self.bound_generic_params_stack.clone(), + ty: P(ty.clone()), + }); } visit::walk_ty(self, ty) @@ -429,8 +427,8 @@ impl<'a> TraitDef<'a> { push: &mut dyn FnMut(Annotatable), from_scratch: bool, ) { - match *item { - Annotatable::Item(ref item) => { + match item { + Annotatable::Item(item) => { let is_packed = item.attrs.iter().any(|attr| { for r in attr::find_repr_attrs(&cx.sess, attr) { if let attr::ReprPacked(_) = r { @@ -439,38 +437,37 @@ impl<'a> TraitDef<'a> { } false }); - let has_no_type_params = match item.kind { - ast::ItemKind::Struct(_, ref generics) - | ast::ItemKind::Enum(_, ref generics) - | ast::ItemKind::Union(_, ref generics) => !generics + let has_no_type_params = match &item.kind { + ast::ItemKind::Struct(_, generics) + | ast::ItemKind::Enum(_, generics) + | ast::ItemKind::Union(_, generics) => !generics .params .iter() .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })), _ => unreachable!(), }; let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); - let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id); + let copy_fields = + is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id); - let newitem = match item.kind { - ast::ItemKind::Struct(ref struct_def, ref generics) => self.expand_struct_def( + let newitem = match &item.kind { + ast::ItemKind::Struct(struct_def, generics) => self.expand_struct_def( cx, &struct_def, item.ident, generics, from_scratch, - is_packed, - always_copy, + copy_fields, ), - ast::ItemKind::Enum(ref enum_def, ref generics) => { - // We ignore `is_packed`/`always_copy` here, because - // `repr(packed)` enums cause an error later on. + ast::ItemKind::Enum(enum_def, generics) => { + // 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. + // downstream in blatantly illegal code, so it is fine. self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch) } - ast::ItemKind::Union(ref struct_def, ref generics) => { + ast::ItemKind::Union(struct_def, generics) => { if self.supports_unions { self.expand_struct_def( cx, @@ -478,8 +475,7 @@ impl<'a> TraitDef<'a> { item.ident, generics, from_scratch, - is_packed, - always_copy, + copy_fields, ) } else { cx.span_err(mitem.span, "this trait cannot be derived for unions"); @@ -581,19 +577,21 @@ impl<'a> TraitDef<'a> { }) }); - let Generics { mut params, mut where_clause, .. } = - self.generics.to_generics(cx, self.span, type_ident, generics); + let mut where_clause = ast::WhereClause::default(); where_clause.span = generics.where_clause.span; let ctxt = self.span.ctxt(); let span = generics.span.with_ctxt(ctxt); // Create the generic parameters - params.extend(generics.params.iter().map(|param| match ¶m.kind { - GenericParamKind::Lifetime { .. } => param.clone(), - GenericParamKind::Type { .. } => { - // I don't think this can be moved out of the loop, since - // a GenericBound requires an ast id - let bounds: Vec<_> = + let params: Vec<_> = generics + .params + .iter() + .map(|param| match ¶m.kind { + GenericParamKind::Lifetime { .. } => param.clone(), + GenericParamKind::Type { .. } => { + // I don't think this can be moved out of the loop, since + // a GenericBound requires an ast id + let bounds: Vec<_> = // extra restrictions on the generics parameters to the // type being derived upon self.additional_bounds.iter().map(|p| { @@ -606,21 +604,22 @@ impl<'a> TraitDef<'a> { param.bounds.iter().cloned() ).collect(); - cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) - } - GenericParamKind::Const { ty, kw_span, .. } => { - let const_nodefault_kind = GenericParamKind::Const { - ty: ty.clone(), - kw_span: kw_span.with_ctxt(ctxt), - - // We can't have default values inside impl block - default: None, - }; - let mut param_clone = param.clone(); - param_clone.kind = const_nodefault_kind; - param_clone - } - })); + cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) + } + GenericParamKind::Const { ty, kw_span, .. } => { + let const_nodefault_kind = GenericParamKind::Const { + ty: ty.clone(), + kw_span: kw_span.with_ctxt(ctxt), + + // We can't have default values inside impl block + default: None, + }; + let mut param_clone = param.clone(); + param_clone.kind = const_nodefault_kind; + param_clone + } + }) + .collect(); // and similarly for where clauses where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| { @@ -663,12 +662,11 @@ impl<'a> TraitDef<'a> { for field_ty_param in field_ty_params { // if we have already handled this type, skip it - if let ast::TyKind::Path(_, ref p) = field_ty_param.ty.kind { - if p.segments.len() == 1 - && ty_param_names.contains(&p.segments[0].ident.name) - { - continue; - }; + if let ast::TyKind::Path(_, p) = &field_ty_param.ty.kind + && let [sole_segment] = &*p.segments + && ty_param_names.contains(&sole_segment.ident.name) + { + continue; } let mut bounds: Vec<_> = self .additional_bounds @@ -718,7 +716,7 @@ impl<'a> TraitDef<'a> { let path = cx.path_all(self.span, false, vec![type_ident], self_params); let self_type = cx.ty_path(path); - let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); + let attr = cx.attr_word(sym::automatically_derived, self.span); let attrs = thin_vec![attr]; let opt_trait_ref = Some(trait_ref); @@ -730,7 +728,7 @@ impl<'a> TraitDef<'a> { unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, - constness: ast::Const::No, + constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No }, generics: trait_generics, of_trait: opt_trait_ref, self_ty: self_type, @@ -746,8 +744,7 @@ impl<'a> TraitDef<'a> { type_ident: Ident, generics: &Generics, from_scratch: bool, - is_packed: bool, - always_copy: bool, + copy_fields: bool, ) -> P { let field_tys: Vec> = struct_def.fields().iter().map(|field| field.ty.clone()).collect(); @@ -775,8 +772,7 @@ impl<'a> TraitDef<'a> { type_ident, &selflike_args, &nonselflike_args, - is_packed, - always_copy, + copy_fields, ) }; @@ -1014,19 +1010,9 @@ impl<'a> MethodDef<'a> { /// } /// } /// ``` - /// If the struct doesn't impl `Copy`, we use let-destructuring with `ref`: - /// ``` - /// # struct A { x: u8, y: u8 } - /// impl PartialEq for A { - /// fn eq(&self, other: &A) -> bool { - /// let Self { x: ref __self_0_0, y: ref __self_0_1 } = *self; - /// let Self { x: ref __self_1_0, y: ref __self_1_1 } = *other; - /// *__self_0_0 == *__self_1_0 && *__self_0_1 == *__self_1_1 - /// } - /// } - /// ``` - /// This latter case only works if the fields match the alignment required - /// by the `packed(N)` attribute. (We'll get errors later on if not.) + /// If the struct doesn't impl `Copy`, we use the normal `&self.x`. This + /// only works if the fields match the alignment required by the + /// `packed(N)` attribute. (We'll get errors later on if not.) fn expand_struct_method_body<'b>( &self, cx: &mut ExtCtxt<'_>, @@ -1035,54 +1021,19 @@ impl<'a> MethodDef<'a> { type_ident: Ident, selflike_args: &[P], nonselflike_args: &[P], - is_packed: bool, - always_copy: bool, + copy_fields: bool, ) -> BlockOrExpr { - let span = trait_.span; assert!(selflike_args.len() == 1 || selflike_args.len() == 2); - let mk_body = |cx, selflike_fields| { - self.call_substructure_method( - cx, - trait_, - type_ident, - nonselflike_args, - &Struct(struct_def, selflike_fields), - ) - }; - - if !is_packed { - let selflike_fields = - trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, false); - mk_body(cx, selflike_fields) - } else if always_copy { - let selflike_fields = - trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, true); - mk_body(cx, selflike_fields) - } else { - // Neither packed nor copy. Need to use ref patterns. - let prefixes: Vec<_> = - (0..selflike_args.len()).map(|i| format!("__self_{}", i)).collect(); - let addr_of = always_copy; - let selflike_fields = - trait_.create_struct_pattern_fields(cx, struct_def, &prefixes, addr_of); - let mut body = mk_body(cx, selflike_fields); - - let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); - let by_ref = ByRef::from(is_packed && !always_copy); - let patterns = - trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref); - - // Do the let-destructuring. - let mut stmts: Vec<_> = iter::zip(selflike_args, patterns) - .map(|(selflike_arg_expr, pat)| { - let selflike_arg_expr = cx.expr_deref(span, selflike_arg_expr.clone()); - cx.stmt_let_pat(span, pat, selflike_arg_expr) - }) - .collect(); - stmts.extend(std::mem::take(&mut body.0)); - BlockOrExpr(stmts, body.1) - } + let selflike_fields = + trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, copy_fields); + self.call_substructure_method( + cx, + trait_, + type_ident, + nonselflike_args, + &Struct(struct_def, selflike_fields), + ) } fn expand_static_struct_method_body( @@ -1252,9 +1203,7 @@ impl<'a> MethodDef<'a> { // A single arm has form (&VariantK, &VariantK, ...) => BodyK // (see "Final wrinkle" note below for why.) - let addr_of = false; // because enums can't be repr(packed) - let fields = - trait_.create_struct_pattern_fields(cx, &variant.data, &prefixes, addr_of); + let fields = trait_.create_struct_pattern_fields(cx, &variant.data, &prefixes); let sp = variant.span.with_ctxt(trait_.span.ctxt()); let variant_path = cx.path(sp, vec![type_ident, variant.ident]); @@ -1517,15 +1466,13 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt<'_>, struct_def: &'a VariantData, prefixes: &[String], - addr_of: bool, ) -> Vec { self.create_fields(struct_def, |i, _struct_field, sp| { prefixes .iter() .map(|prefix| { let ident = self.mk_pattern_ident(prefix, i); - let expr = cx.expr_path(cx.path_ident(sp, ident)); - if addr_of { cx.expr_addr_of(sp, expr) } else { expr } + cx.expr_path(cx.path_ident(sp, ident)) }) .collect() }) @@ -1536,7 +1483,7 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt<'_>, selflike_args: &[P], struct_def: &'a VariantData, - copy: bool, + copy_fields: bool, ) -> Vec { self.create_fields(struct_def, |i, struct_field, sp| { selflike_args @@ -1555,7 +1502,7 @@ impl<'a> TraitDef<'a> { }), ), ); - if copy { + if copy_fields { field_expr = cx.expr_block( cx.block(struct_field.span, vec![cx.stmt_expr(field_expr)]), ); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 36e2e2930..eaa488190 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -115,7 +115,7 @@ impl Ty { self_ty: Ident, generics: &Generics, ) -> ast::Path { - match *self { + match self { Self_ => { let params: Vec<_> = generics .params @@ -135,7 +135,7 @@ impl Ty { cx.path_all(span, false, vec![self_ty], params) } - Path(ref p) => p.to_path(cx, span, self_ty, generics), + Path(p) => p.to_path(cx, span, self_ty, generics), Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"), Unit => cx.span_bug(span, "unit in a path in generic `derive`"), } @@ -180,10 +180,7 @@ impl Bounds { let params = self .bounds .iter() - .map(|t| { - let (name, ref bounds) = *t; - mk_ty_param(cx, span, name, &bounds, self_ty, self_generics) - }) + .map(|&(name, ref bounds)| mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)) .collect(); Generics { diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 6e9d5f08b..c136bb714 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_hash( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std); @@ -24,7 +25,6 @@ pub fn expand_deriving_hash( path, skip_path_as_bound: false, additional_bounds: Vec::new(), - generics: Bounds::empty(), supports_unions: false, methods: vec![MethodDef { name: sym::hash, @@ -39,6 +39,7 @@ pub fn expand_deriving_hash( })), }], associated_types: Vec::new(), + is_const, }; hash_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 ee346047a..de657e4e6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -38,9 +38,10 @@ pub mod partial_ord; pub mod generic; -pub(crate) struct BuiltinDerive( - pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)), -); +pub(crate) type BuiltinDeriveFn = + fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool); + +pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn); impl MultiItemModifier for BuiltinDerive { fn expand( @@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive { span: Span, meta_item: &MetaItem, item: Annotatable, + is_derive_const: bool, ) -> ExpandResult, Annotatable> { // FIXME: Built-in derives often forget to give spans contexts, // so we are doing it here in a centralized way. @@ -57,21 +59,28 @@ impl MultiItemModifier for BuiltinDerive { match item { Annotatable::Stmt(stmt) => { if let ast::StmtKind::Item(item) = stmt.into_inner().kind { - (self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| { - // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' - // to the function - items.push(Annotatable::Stmt(P(ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Item(a.expect_item()), - span, - }))); - }); + (self.0)( + ecx, + span, + meta_item, + &Annotatable::Item(item), + &mut |a| { + // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' + // to the function + items.push(Annotatable::Stmt(P(ast::Stmt { + id: ast::DUMMY_NODE_ID, + kind: ast::StmtKind::Item(a.expect_item()), + span, + }))); + }, + is_derive_const, + ); } else { unreachable!("should have already errored on non-item statement") } } _ => { - (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); + (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const); } } ExpandResult::Ready(items) @@ -116,12 +125,12 @@ fn inject_impl_of_structural_trait( structural_path: generic::ty::Path, push: &mut dyn FnMut(Annotatable), ) { - let Annotatable::Item(ref item) = *item else { + let Annotatable::Item(item) = item else { unreachable!(); }; - let generics = match item.kind { - ItemKind::Struct(_, ref generics) | ItemKind::Enum(_, ref generics) => generics, + let generics = match &item.kind { + ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics, // Do not inject `impl Structural for Union`. (`PartialEq` does not // support unions, so we will see error downstream.) ItemKind::Union(..) => return, @@ -179,7 +188,7 @@ fn inject_impl_of_structural_trait( .cloned(), ); // Mark as `automatically_derived` to avoid some silly lints. - attrs.push(cx.attribute(cx.meta_word(span, sym::automatically_derived))); + attrs.push(cx.attr_word(sym::automatically_derived, span)); let newitem = cx.item( span, -- cgit v1.2.3