summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros/src/deriving
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /compiler/rustc_builtin_macros/src/deriving
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_builtin_macros/src/deriving')
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs22
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs15
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs23
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs21
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs11
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs225
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs43
14 files changed, 176 insertions, 221 deletions
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<F>(
where
F: FnMut(&mut ExtCtxt<'_>, Span, Symbol, usize) -> P<Expr>,
{
- 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<Ty>,
- /// 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<MethodDef<'a>>,
pub associated_types: Vec<(Ident, Ty)>,
+
+ pub is_const: bool,
}
pub struct MethodDef<'a> {
@@ -301,12 +300,12 @@ struct TypeParameter {
ty: P<ast::Ty>,
}
-// 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<ast::Stmt>, Option<P<Expr>>);
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 &param.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 &param.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<ast::Item> {
let field_tys: Vec<P<ast::Ty>> =
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<Expr>],
nonselflike_args: &[P<Expr>],
- 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<FieldInfo> {
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<Expr>],
struct_def: &'a VariantData,
- copy: bool,
+ copy_fields: bool,
) -> Vec<FieldInfo> {
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<Vec<Annotatable>, 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,