mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Rollup merge of #98915 - nnethercote:clarify-deriving-code, r=Mark-Simulacrum
Clarify deriving code A number of clarifications to the deriving code. r? ``@Mark-Simulacrum``
This commit is contained in:
commit
5e6812b597
@ -80,7 +80,7 @@ pub fn expand_deriving_clone(
|
||||
name: sym::clone,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: Vec::new(),
|
||||
nonself_args: Vec::new(),
|
||||
ret_ty: Self_,
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: false,
|
||||
@ -160,8 +160,8 @@ fn cs_clone(
|
||||
let ctor_path;
|
||||
let all_fields;
|
||||
let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]);
|
||||
let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo<'_>| {
|
||||
let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
|
||||
let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo| {
|
||||
let args = vec![cx.expr_addr_of(field.span, field.self_expr.clone())];
|
||||
cx.expr_call_global(field.span, fn_path.clone(), args)
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub fn expand_deriving_eq(
|
||||
name: sym::assert_receiver_is_total_eq,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: vec![],
|
||||
nonself_args: vec![],
|
||||
ret_ty: Unit,
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: true,
|
||||
|
@ -2,8 +2,7 @@ use crate::deriving::generic::ty::*;
|
||||
use crate::deriving::generic::*;
|
||||
use crate::deriving::path_std;
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, MetaItem};
|
||||
use rustc_ast::MetaItem;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
@ -28,7 +27,7 @@ pub fn expand_deriving_ord(
|
||||
name: sym::cmp,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: vec![(self_ref(), sym::other)],
|
||||
nonself_args: vec![(self_ref(), sym::other)],
|
||||
ret_ty: Path(path_std!(cmp::Ordering)),
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: true,
|
||||
@ -40,84 +39,54 @@ pub fn expand_deriving_ord(
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
||||
pub fn ordering_collapsed(
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
self_arg_tags: &[Ident],
|
||||
) -> P<ast::Expr> {
|
||||
let lft = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[0]));
|
||||
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
|
||||
let fn_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
|
||||
cx.expr_call_global(span, fn_cmp_path, vec![lft, rgt])
|
||||
}
|
||||
|
||||
pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
|
||||
let test_id = Ident::new(sym::cmp, span);
|
||||
let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
|
||||
|
||||
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]);
|
||||
|
||||
// Builds:
|
||||
//
|
||||
// match ::std::cmp::Ord::cmp(&self_field1, &other_field1) {
|
||||
// ::std::cmp::Ordering::Equal =>
|
||||
// match ::std::cmp::Ord::cmp(&self_field2, &other_field2) {
|
||||
// ::std::cmp::Ordering::Equal => {
|
||||
// ...
|
||||
// match ::core::cmp::Ord::cmp(&self.x, &other.x) {
|
||||
// ::std::cmp::Ordering::Equal =>
|
||||
// ::core::cmp::Ord::cmp(&self.y, &other.y),
|
||||
// cmp => cmp,
|
||||
// }
|
||||
// cmp => cmp
|
||||
// },
|
||||
// cmp => cmp
|
||||
// }
|
||||
//
|
||||
let expr = cs_fold(
|
||||
// foldr nests the if-elses correctly, leaving the first field
|
||||
// as the outermost one, and the last as the innermost.
|
||||
false,
|
||||
|cx, span, old, self_f, other_fs| {
|
||||
// match new {
|
||||
// ::std::cmp::Ordering::Equal => old,
|
||||
// cmp => cmp
|
||||
// }
|
||||
let new = {
|
||||
let [other_f] = other_fs else {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`");
|
||||
};
|
||||
let args =
|
||||
vec![cx.expr_addr_of(span, self_f), cx.expr_addr_of(span, other_f.clone())];
|
||||
cx.expr_call_global(span, cmp_path.clone(), args)
|
||||
};
|
||||
|
||||
let eq_arm = cx.arm(span, cx.pat_path(span, equals_path.clone()), old);
|
||||
let neq_arm = cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
|
||||
|
||||
cx.expr_match(span, new, vec![eq_arm, neq_arm])
|
||||
},
|
||||
|cx, args| match args {
|
||||
Some((span, self_f, other_fs)) => {
|
||||
let new = {
|
||||
let [other_f] = other_fs else {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`");
|
||||
};
|
||||
let args =
|
||||
vec![cx.expr_addr_of(span, self_f), cx.expr_addr_of(span, other_f.clone())];
|
||||
cx.expr_call_global(span, cmp_path.clone(), args)
|
||||
};
|
||||
|
||||
new
|
||||
}
|
||||
None => cx.expr_path(equals_path.clone()),
|
||||
},
|
||||
Box::new(|cx, span, tag_tuple| {
|
||||
if tag_tuple.len() != 2 {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
|
||||
} else {
|
||||
ordering_collapsed(cx, span, tag_tuple)
|
||||
}
|
||||
}),
|
||||
cx,
|
||||
span,
|
||||
substr,
|
||||
|cx, fold| match fold {
|
||||
CsFold::Single(field) => {
|
||||
let [other_expr] = &field.other_selflike_exprs[..] else {
|
||||
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
|
||||
};
|
||||
let args = vec![
|
||||
cx.expr_addr_of(field.span, field.self_expr.clone()),
|
||||
cx.expr_addr_of(field.span, other_expr.clone()),
|
||||
];
|
||||
cx.expr_call_global(field.span, cmp_path.clone(), args)
|
||||
}
|
||||
CsFold::Combine(span, expr1, expr2) => {
|
||||
let eq_arm = cx.arm(span, cx.pat_path(span, equal_path.clone()), expr1);
|
||||
let neq_arm =
|
||||
cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
|
||||
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
|
||||
}
|
||||
CsFold::Fieldless => cx.expr_path(equal_path.clone()),
|
||||
CsFold::EnumNonMatching(span, tag_tuple) => {
|
||||
if tag_tuple.len() != 2 {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`")
|
||||
} else {
|
||||
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
|
||||
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
|
||||
let fn_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
|
||||
cx.expr_call_global(span, fn_cmp_path, vec![lft, rgt])
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
BlockOrExpr::new_expr(expr)
|
||||
}
|
||||
|
@ -2,8 +2,7 @@ use crate::deriving::generic::ty::*;
|
||||
use crate::deriving::generic::*;
|
||||
use crate::deriving::{path_local, path_std};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{BinOpKind, Expr, MetaItem};
|
||||
use rustc_ast::{BinOpKind, MetaItem};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
@ -23,33 +22,22 @@ pub fn expand_deriving_partial_eq(
|
||||
combiner: BinOpKind,
|
||||
base: bool,
|
||||
) -> BlockOrExpr {
|
||||
let op = |cx: &mut ExtCtxt<'_>, span: Span, self_f: P<Expr>, other_fs: &[P<Expr>]| {
|
||||
let [other_f] = other_fs else {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`");
|
||||
};
|
||||
|
||||
cx.expr_binary(span, op, self_f, other_f.clone())
|
||||
};
|
||||
|
||||
let expr = cs_fold(
|
||||
true, // use foldl
|
||||
|cx, span, subexpr, self_f, other_fs| {
|
||||
let eq = op(cx, span, self_f, other_fs);
|
||||
cx.expr_binary(span, combiner, subexpr, eq)
|
||||
},
|
||||
|cx, args| {
|
||||
match args {
|
||||
Some((span, self_f, other_fs)) => {
|
||||
// Special-case the base case to generate cleaner code.
|
||||
op(cx, span, self_f, other_fs)
|
||||
}
|
||||
None => cx.expr_bool(span, base),
|
||||
}
|
||||
},
|
||||
Box::new(|cx, span, _| cx.expr_bool(span, !base)),
|
||||
cx,
|
||||
span,
|
||||
substr,
|
||||
|cx, fold| match fold {
|
||||
CsFold::Single(field) => {
|
||||
let [other_expr] = &field.other_selflike_exprs[..] else {
|
||||
cx.span_bug(field.span, "not exactly 2 arguments in `derive(PartialEq)`");
|
||||
};
|
||||
cx.expr_binary(field.span, op, field.self_expr.clone(), other_expr.clone())
|
||||
}
|
||||
CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
|
||||
CsFold::Fieldless => cx.expr_bool(span, base),
|
||||
CsFold::EnumNonMatching(span, _tag_tuple) => cx.expr_bool(span, !base),
|
||||
},
|
||||
);
|
||||
BlockOrExpr::new_expr(expr)
|
||||
}
|
||||
@ -69,7 +57,7 @@ pub fn expand_deriving_partial_eq(
|
||||
name: $name,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: vec![(self_ref(), sym::other)],
|
||||
nonself_args: vec![(self_ref(), sym::other)],
|
||||
ret_ty: Path(path_local!(bool)),
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: true,
|
||||
|
@ -2,8 +2,7 @@ use crate::deriving::generic::ty::*;
|
||||
use crate::deriving::generic::*;
|
||||
use crate::deriving::{path_std, pathvec_std};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{Expr, MetaItem};
|
||||
use rustc_ast::MetaItem;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
@ -26,7 +25,7 @@ pub fn expand_deriving_partial_ord(
|
||||
name: sym::partial_cmp,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: vec![(self_ref(), sym::other)],
|
||||
nonself_args: vec![(self_ref(), sym::other)],
|
||||
ret_ty,
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: true,
|
||||
@ -50,79 +49,54 @@ pub fn expand_deriving_partial_ord(
|
||||
|
||||
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
|
||||
let test_id = Ident::new(sym::cmp, span);
|
||||
let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
|
||||
let ordering_expr = cx.expr_path(ordering.clone());
|
||||
|
||||
let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
|
||||
let partial_cmp_path = cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
|
||||
|
||||
// Builds:
|
||||
//
|
||||
// match ::std::cmp::PartialOrd::partial_cmp(&self_field1, &other_field1) {
|
||||
// ::std::option::Option::Some(::std::cmp::Ordering::Equal) =>
|
||||
// match ::std::cmp::PartialOrd::partial_cmp(&self_field2, &other_field2) {
|
||||
// ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {
|
||||
// ...
|
||||
// match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
|
||||
// ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
|
||||
// ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
|
||||
// cmp => cmp,
|
||||
// }
|
||||
// cmp => cmp
|
||||
// },
|
||||
// cmp => cmp
|
||||
// }
|
||||
//
|
||||
let expr = cs_fold(
|
||||
// foldr nests the if-elses correctly, leaving the first field
|
||||
// as the outermost one, and the last as the innermost.
|
||||
false,
|
||||
|cx, span, old, self_f, other_fs| {
|
||||
// match new {
|
||||
// Some(::std::cmp::Ordering::Equal) => old,
|
||||
// cmp => cmp
|
||||
// }
|
||||
|
||||
let new = {
|
||||
let [other_f] = other_fs else {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`");
|
||||
};
|
||||
|
||||
let args =
|
||||
vec![cx.expr_addr_of(span, self_f), cx.expr_addr_of(span, other_f.clone())];
|
||||
|
||||
cx.expr_call_global(span, partial_cmp_path.clone(), args)
|
||||
};
|
||||
|
||||
let eq_arm = cx.arm(span, cx.pat_some(span, cx.pat_path(span, ordering.clone())), old);
|
||||
let neq_arm = cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
|
||||
|
||||
cx.expr_match(span, new, vec![eq_arm, neq_arm])
|
||||
},
|
||||
|cx: &mut ExtCtxt<'_>, args: Option<(Span, P<Expr>, &[P<Expr>])>| match args {
|
||||
Some((span, self_f, other_fs)) => {
|
||||
let new = {
|
||||
let [other_f] = other_fs else {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`");
|
||||
};
|
||||
let args =
|
||||
vec![cx.expr_addr_of(span, self_f), cx.expr_addr_of(span, other_f.clone())];
|
||||
cx.expr_call_global(span, partial_cmp_path.clone(), args)
|
||||
};
|
||||
|
||||
new
|
||||
}
|
||||
None => cx.expr_some(span, ordering_expr.clone()),
|
||||
},
|
||||
Box::new(|cx, span, tag_tuple| {
|
||||
if tag_tuple.len() != 2 {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
|
||||
} else {
|
||||
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
|
||||
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
|
||||
let fn_partial_cmp_path =
|
||||
cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
|
||||
cx.expr_call_global(span, fn_partial_cmp_path, vec![lft, rgt])
|
||||
}
|
||||
}),
|
||||
cx,
|
||||
span,
|
||||
substr,
|
||||
|cx, fold| match fold {
|
||||
CsFold::Single(field) => {
|
||||
let [other_expr] = &field.other_selflike_exprs[..] else {
|
||||
cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
|
||||
};
|
||||
let args = vec![
|
||||
cx.expr_addr_of(field.span, field.self_expr.clone()),
|
||||
cx.expr_addr_of(field.span, other_expr.clone()),
|
||||
];
|
||||
cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
|
||||
}
|
||||
CsFold::Combine(span, expr1, expr2) => {
|
||||
let eq_arm =
|
||||
cx.arm(span, cx.pat_some(span, cx.pat_path(span, equal_path.clone())), expr1);
|
||||
let neq_arm =
|
||||
cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id));
|
||||
cx.expr_match(span, expr2, vec![eq_arm, neq_arm])
|
||||
}
|
||||
CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())),
|
||||
CsFold::EnumNonMatching(span, tag_tuple) => {
|
||||
if tag_tuple.len() != 2 {
|
||||
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
|
||||
} else {
|
||||
let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0]));
|
||||
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
|
||||
let fn_partial_cmp_path =
|
||||
cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]);
|
||||
cx.expr_call_global(span, fn_partial_cmp_path, vec![lft, rgt])
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
BlockOrExpr::new_expr(expr)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ pub fn expand_deriving_debug(
|
||||
name: sym::fmt,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: true,
|
||||
args: vec![(fmtr, sym::f)],
|
||||
nonself_args: vec![(fmtr, sym::f)],
|
||||
ret_ty: Path(path_std!(fmt::Result)),
|
||||
attributes: Vec::new(),
|
||||
unify_fieldless_variants: false,
|
||||
@ -53,7 +53,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||
// 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);
|
||||
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
|
||||
let fmt = substr.nonself_args[0].clone();
|
||||
let fmt = substr.nonselflike_args[0].clone();
|
||||
|
||||
// Struct and tuples are similar enough that we use the same code for both,
|
||||
// with some extra pieces for structs due to the field names.
|
||||
@ -96,7 +96,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||
args.push(name);
|
||||
}
|
||||
// Use double indirection to make sure this works for unsized types
|
||||
let field = cx.expr_addr_of(field.span, field.self_.clone());
|
||||
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
|
||||
let field = cx.expr_addr_of(field.span, field);
|
||||
args.push(field);
|
||||
}
|
||||
@ -116,7 +116,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
|
||||
}
|
||||
|
||||
// Use double indirection to make sure this works for unsized types
|
||||
let value_ref = cx.expr_addr_of(field.span, field.self_.clone());
|
||||
let value_ref = cx.expr_addr_of(field.span, field.self_expr.clone());
|
||||
value_exprs.push(cx.expr_addr_of(field.span, value_ref));
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,10 @@ pub fn expand_deriving_rustc_decodable(
|
||||
)],
|
||||
},
|
||||
explicit_self: false,
|
||||
args: vec![(Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut), sym::d)],
|
||||
nonself_args: vec![(
|
||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
||||
sym::d,
|
||||
)],
|
||||
ret_ty: Path(Path::new_(
|
||||
pathvec_std!(result::Result),
|
||||
vec![
|
||||
@ -63,7 +66,7 @@ fn decodable_substructure(
|
||||
substr: &Substructure<'_>,
|
||||
krate: Symbol,
|
||||
) -> BlockOrExpr {
|
||||
let decoder = substr.nonself_args[0].clone();
|
||||
let decoder = substr.nonselflike_args[0].clone();
|
||||
let recurse = vec![
|
||||
Ident::new(krate, trait_span),
|
||||
Ident::new(sym::Decodable, trait_span),
|
||||
|
@ -34,7 +34,7 @@ pub fn expand_deriving_default(
|
||||
name: kw::Default,
|
||||
generics: Bounds::empty(),
|
||||
explicit_self: false,
|
||||
args: Vec::new(),
|
||||
nonself_args: Vec::new(),
|
||||
ret_ty: Self_,
|
||||
attributes: attrs,
|
||||
unify_fieldless_variants: false,
|
||||
|
@ -120,7 +120,10 @@ pub fn expand_deriving_rustc_encodable(
|
||||
)],
|
||||
},
|
||||
explicit_self: true,
|
||||
args: vec![(Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut), sym::s)],
|
||||
nonself_args: vec![(
|
||||
Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut),
|
||||
sym::s,
|
||||
)],
|
||||
ret_ty: Path(Path::new_(
|
||||
pathvec_std!(result::Result),
|
||||
vec![
|
||||
@ -147,7 +150,7 @@ fn encodable_substructure(
|
||||
substr: &Substructure<'_>,
|
||||
krate: Symbol,
|
||||
) -> BlockOrExpr {
|
||||
let encoder = substr.nonself_args[0].clone();
|
||||
let encoder = substr.nonselflike_args[0].clone();
|
||||
// throw an underscore in front to suppress unused variable warnings
|
||||
let blkarg = Ident::new(sym::_e, trait_span);
|
||||
let blkencoder = cx.expr_ident(trait_span, blkarg);
|
||||
@ -165,12 +168,12 @@ fn encodable_substructure(
|
||||
let fn_emit_struct_field_path =
|
||||
cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]);
|
||||
let mut stmts = Vec::new();
|
||||
for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
|
||||
for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() {
|
||||
let name = match name {
|
||||
Some(id) => id.name,
|
||||
None => Symbol::intern(&format!("_field{}", i)),
|
||||
};
|
||||
let self_ref = cx.expr_addr_of(span, self_.clone());
|
||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
||||
let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
|
||||
let lambda = cx.lambda1(span, enc, blkarg);
|
||||
let call = cx.expr_call_global(
|
||||
@ -234,8 +237,8 @@ fn encodable_substructure(
|
||||
let mut stmts = Vec::new();
|
||||
if !fields.is_empty() {
|
||||
let last = fields.len() - 1;
|
||||
for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
|
||||
let self_ref = cx.expr_addr_of(span, self_.clone());
|
||||
for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() {
|
||||
let self_ref = cx.expr_addr_of(span, self_expr.clone());
|
||||
let enc =
|
||||
cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
|
||||
let lambda = cx.lambda1(span, enc, blkarg);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ pub fn expand_deriving_hash(
|
||||
name: sym::hash,
|
||||
generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
|
||||
explicit_self: true,
|
||||
args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
|
||||
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
|
||||
ret_ty: Unit,
|
||||
attributes: vec![],
|
||||
unify_fieldless_variants: true,
|
||||
@ -49,7 +49,7 @@ fn hash_substructure(
|
||||
trait_span: Span,
|
||||
substr: &Substructure<'_>,
|
||||
) -> BlockOrExpr {
|
||||
let [state_expr] = substr.nonself_args else {
|
||||
let [state_expr] = substr.nonselflike_args else {
|
||||
cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`");
|
||||
};
|
||||
let call_hash = |span, thing_expr| {
|
||||
@ -82,7 +82,9 @@ fn hash_substructure(
|
||||
};
|
||||
|
||||
stmts.extend(
|
||||
fields.iter().map(|FieldInfo { ref self_, span, .. }| call_hash(*span, self_.clone())),
|
||||
fields
|
||||
.iter()
|
||||
.map(|FieldInfo { ref self_expr, span, .. }| call_hash(*span, self_expr.clone())),
|
||||
);
|
||||
BlockOrExpr::new_stmts(stmts)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user