1 use crate::deriving
::generic
::ty
::*;
2 use crate::deriving
::generic
::*;
3 use crate::deriving
::path_std
;
5 use rustc_ast
::ast
::{self, Expr, GenericArg, MetaItem}
;
7 use rustc_expand
::base
::{Annotatable, ExtCtxt}
;
8 use rustc_span
::symbol
::{sym, Ident, Symbol}
;
11 pub fn expand_deriving_eq(
16 push
: &mut dyn FnMut(Annotatable
),
18 let inline
= cx
.meta_word(span
, sym
::inline
);
19 let hidden
= rustc_ast
::attr
::mk_nested_word_item(Ident
::new(sym
::hidden
, span
));
20 let doc
= rustc_ast
::attr
::mk_list_item(Ident
::new(sym
::doc
, span
), vec
![hidden
]);
21 let attrs
= vec
![cx
.attribute(inline
), cx
.attribute(doc
)];
22 let trait_def
= TraitDef
{
24 attributes
: Vec
::new(),
25 path
: path_std
!(cx
, cmp
::Eq
),
26 additional_bounds
: Vec
::new(),
27 generics
: LifetimeBounds
::empty(),
29 supports_unions
: true,
30 methods
: vec
![MethodDef
{
31 name
: "assert_receiver_is_total_eq",
32 generics
: LifetimeBounds
::empty(),
33 explicit_self
: borrowed_explicit_self(),
38 unify_fieldless_variants
: true,
39 combine_substructure
: combine_substructure(Box
::new(|a
, b
, c
| {
40 cs_total_eq_assert(a
, b
, c
)
43 associated_types
: Vec
::new(),
46 super::inject_impl_of_structural_trait(
50 path_std
!(cx
, marker
::StructuralEq
),
54 trait_def
.expand_ext(cx
, mitem
, item
, push
, true)
57 fn cs_total_eq_assert(
60 substr
: &Substructure
<'_
>,
64 stmts
: &mut Vec
<ast
::Stmt
>,
69 // Generate statement `let _: helper_name<ty>;`,
70 // set the expn ID so we can use the unstable struct.
71 let span
= cx
.with_def_site_ctxt(span
);
72 let assert_path
= cx
.path_all(
75 cx
.std_path(&[sym
::cmp
, Symbol
::intern(helper_name
)]),
76 vec
![GenericArg
::Type(ty
)],
78 stmts
.push(cx
.stmt_let_type_only(span
, cx
.ty_path(assert_path
)));
82 stmts
: &mut Vec
<ast
::Stmt
>,
83 variant
: &ast
::VariantData
,
85 for field
in variant
.fields() {
86 // let _: AssertParamIsEq<FieldTy>;
87 assert_ty_bounds(cx
, stmts
, field
.ty
.clone(), field
.span
, "AssertParamIsEq");
91 let mut stmts
= Vec
::new();
92 match *substr
.fields
{
93 StaticStruct(vdata
, ..) => {
94 process_variant(cx
, &mut stmts
, vdata
);
96 StaticEnum(enum_def
, ..) => {
97 for variant
in &enum_def
.variants
{
98 process_variant(cx
, &mut stmts
, &variant
.data
);
101 _
=> cx
.span_bug(trait_span
, "unexpected substructure in `derive(Eq)`"),
103 cx
.expr_block(cx
.block(trait_span
, stmts
))