]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
1 use crate::deriving
::generic
::ty
::*;
2 use crate::deriving
::generic
::*;
3 use crate::deriving
::{path_std, pathvec_std}
;
4 use rustc_ast
::MetaItem
;
5 use rustc_expand
::base
::{Annotatable, ExtCtxt}
;
6 use rustc_span
::symbol
::{sym, Ident}
;
8 use thin_vec
::thin_vec
;
10 pub fn expand_deriving_partial_ord(
15 push
: &mut dyn FnMut(Annotatable
),
18 let ordering_ty
= Path(path_std
!(cmp
::Ordering
));
20 Path(Path
::new_(pathvec_std
!(option
::Option
), vec
![Box
::new(ordering_ty
)], PathKind
::Std
));
22 let attrs
= thin_vec
![cx
.attr_word(sym
::inline
, span
)];
24 let partial_cmp_def
= MethodDef
{
25 name
: sym
::partial_cmp
,
26 generics
: Bounds
::empty(),
28 nonself_args
: vec
![(self_ref(), sym
::other
)],
31 unify_fieldless_variants
: true,
32 combine_substructure
: combine_substructure(Box
::new(|cx
, span
, substr
| {
33 cs_partial_cmp(cx
, span
, substr
)
37 let trait_def
= TraitDef
{
39 path
: path_std
!(cmp
::PartialOrd
),
40 skip_path_as_bound
: false,
41 additional_bounds
: vec
![],
42 supports_unions
: false,
43 methods
: vec
![partial_cmp_def
],
44 associated_types
: Vec
::new(),
47 trait_def
.expand(cx
, mitem
, item
, push
)
50 pub fn cs_partial_cmp(cx
: &mut ExtCtxt
<'_
>, span
: Span
, substr
: &Substructure
<'_
>) -> BlockOrExpr
{
51 let test_id
= Ident
::new(sym
::cmp
, span
);
52 let equal_path
= cx
.path_global(span
, cx
.std_path(&[sym
::cmp
, sym
::Ordering
, sym
::Equal
]));
53 let partial_cmp_path
= cx
.std_path(&[sym
::cmp
, sym
::PartialOrd
, sym
::partial_cmp
]);
57 // match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
58 // ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
59 // ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
63 // foldr nests the if-elses correctly, leaving the first field
64 // as the outermost one, and the last as the innermost.
69 |cx
, fold
| match fold
{
70 CsFold
::Single(field
) => {
71 let [other_expr
] = &field
.other_selflike_exprs
[..] else {
72 cx
.span_bug(field
.span
, "not exactly 2 arguments in `derive(Ord)`");
74 let args
= vec
![field
.self_expr
.clone(), other_expr
.clone()];
75 cx
.expr_call_global(field
.span
, partial_cmp_path
.clone(), args
)
77 CsFold
::Combine(span
, expr1
, expr2
) => {
79 cx
.arm(span
, cx
.pat_some(span
, cx
.pat_path(span
, equal_path
.clone())), expr1
);
81 cx
.arm(span
, cx
.pat_ident(span
, test_id
), cx
.expr_ident(span
, test_id
));
82 cx
.expr_match(span
, expr2
, vec
![eq_arm
, neq_arm
])
84 CsFold
::Fieldless
=> cx
.expr_some(span
, cx
.expr_path(equal_path
.clone())),
87 BlockOrExpr
::new_expr(expr
)