1- pub use OrderingOp :: * ;
2-
31use crate :: deriving:: generic:: ty:: * ;
42use crate :: deriving:: generic:: * ;
5- use crate :: deriving:: { path_local , path_std, pathvec_std} ;
3+ use crate :: deriving:: { path_std, pathvec_std} ;
64
75use rustc_ast:: ptr:: P ;
8- use rustc_ast:: { self as ast , BinOpKind , Expr , MetaItem } ;
6+ use rustc_ast:: { Expr , MetaItem } ;
97use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
10- use rustc_span:: symbol:: { sym, Ident , Symbol } ;
8+ use rustc_span:: symbol:: { sym, Ident } ;
119use rustc_span:: Span ;
1210
1311pub fn expand_deriving_partial_ord (
@@ -17,26 +15,6 @@ pub fn expand_deriving_partial_ord(
1715 item : & Annotatable ,
1816 push : & mut dyn FnMut ( Annotatable ) ,
1917) {
20- macro_rules! md {
21- ( $name: expr, $op: expr, $equal: expr) => { {
22- let inline = cx. meta_word( span, sym:: inline) ;
23- let attrs = vec![ cx. attribute( inline) ] ;
24- MethodDef {
25- name: $name,
26- generics: Bounds :: empty( ) ,
27- explicit_self: borrowed_explicit_self( ) ,
28- args: vec![ ( borrowed_self( ) , sym:: other) ] ,
29- ret_ty: Literal ( path_local!( bool ) ) ,
30- attributes: attrs,
31- is_unsafe: false ,
32- unify_fieldless_variants: true ,
33- combine_substructure: combine_substructure( Box :: new( |cx, span, substr| {
34- cs_op( $op, $equal, cx, span, substr)
35- } ) ) ,
36- }
37- } } ;
38- }
39-
4018 let ordering_ty = Literal ( path_std ! ( cmp:: Ordering ) ) ;
4119 let ret_ty = Literal ( Path :: new_ (
4220 pathvec_std ! ( option:: Option ) ,
@@ -62,21 +40,6 @@ pub fn expand_deriving_partial_ord(
6240 } ) ) ,
6341 } ;
6442
65- // avoid defining extra methods if we can
66- // c-like enums, enums without any fields and structs without fields
67- // can safely define only `partial_cmp`.
68- let methods = if is_type_without_fields ( item) {
69- vec ! [ partial_cmp_def]
70- } else {
71- vec ! [
72- partial_cmp_def,
73- md!( sym:: lt, true , false ) ,
74- md!( sym:: le, true , true ) ,
75- md!( sym:: gt, false , false ) ,
76- md!( sym:: ge, false , true ) ,
77- ]
78- } ;
79-
8043 let trait_def = TraitDef {
8144 span,
8245 attributes : vec ! [ ] ,
@@ -85,39 +48,12 @@ pub fn expand_deriving_partial_ord(
8548 generics : Bounds :: empty ( ) ,
8649 is_unsafe : false ,
8750 supports_unions : false ,
88- methods,
51+ methods : vec ! [ partial_cmp_def ] ,
8952 associated_types : Vec :: new ( ) ,
9053 } ;
9154 trait_def. expand ( cx, mitem, item, push)
9255}
9356
94- #[ derive( Copy , Clone ) ]
95- pub enum OrderingOp {
96- PartialCmpOp ,
97- LtOp ,
98- LeOp ,
99- GtOp ,
100- GeOp ,
101- }
102-
103- pub fn some_ordering_collapsed (
104- cx : & mut ExtCtxt < ' _ > ,
105- span : Span ,
106- op : OrderingOp ,
107- self_arg_tags : & [ Ident ] ,
108- ) -> P < ast:: Expr > {
109- let lft = cx. expr_ident ( span, self_arg_tags[ 0 ] ) ;
110- let rgt = cx. expr_addr_of ( span, cx. expr_ident ( span, self_arg_tags[ 1 ] ) ) ;
111- let op_sym = match op {
112- PartialCmpOp => sym:: partial_cmp,
113- LtOp => sym:: lt,
114- LeOp => sym:: le,
115- GtOp => sym:: gt,
116- GeOp => sym:: ge,
117- } ;
118- cx. expr_method_call ( span, lft, Ident :: new ( op_sym, span) , vec ! [ rgt] )
119- }
120-
12157pub fn cs_partial_cmp ( cx : & mut ExtCtxt < ' _ > , span : Span , substr : & Substructure < ' _ > ) -> P < Expr > {
12258 let test_id = Ident :: new ( sym:: cmp, span) ;
12359 let ordering = cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , sym:: Equal ] ) ) ;
@@ -171,132 +107,13 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
171107 if self_args. len ( ) != 2 {
172108 cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
173109 } else {
174- some_ordering_collapsed ( cx, span, PartialCmpOp , tag_tuple)
110+ let lft = cx. expr_ident ( span, tag_tuple[ 0 ] ) ;
111+ let rgt = cx. expr_addr_of ( span, cx. expr_ident ( span, tag_tuple[ 1 ] ) ) ;
112+ cx. expr_method_call ( span, lft, Ident :: new ( sym:: partial_cmp, span) , vec ! [ rgt] )
175113 }
176114 } ) ,
177115 cx,
178116 span,
179117 substr,
180118 )
181119}
182-
183- /// Strict inequality.
184- fn cs_op (
185- less : bool ,
186- inclusive : bool ,
187- cx : & mut ExtCtxt < ' _ > ,
188- span : Span ,
189- substr : & Substructure < ' _ > ,
190- ) -> P < Expr > {
191- let ordering_path = |cx : & mut ExtCtxt < ' _ > , name : & str | {
192- cx. expr_path (
193- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , Symbol :: intern ( name) ] ) ) ,
194- )
195- } ;
196-
197- let par_cmp = |cx : & mut ExtCtxt < ' _ > , span, self_f : P < Expr > , other_fs : & [ P < Expr > ] , default| {
198- let other_f = match other_fs {
199- [ o_f] => o_f,
200- _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" ) ,
201- } ;
202-
203- // `PartialOrd::partial_cmp(self.fi, other.fi)`
204- let cmp_path = cx. expr_path (
205- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: PartialOrd , sym:: partial_cmp] ) ) ,
206- ) ;
207- let cmp = cx. expr_call (
208- span,
209- cmp_path,
210- vec ! [ cx. expr_addr_of( span, self_f) , cx. expr_addr_of( span, other_f. clone( ) ) ] ,
211- ) ;
212-
213- let default = ordering_path ( cx, default) ;
214- // `Option::unwrap_or(_, Ordering::Equal)`
215- let unwrap_path = cx. expr_path (
216- cx. path_global ( span, cx. std_path ( & [ sym:: option, sym:: Option , sym:: unwrap_or] ) ) ,
217- ) ;
218- cx. expr_call ( span, unwrap_path, vec ! [ cmp, default ] )
219- } ;
220-
221- let fold = cs_fold1 (
222- false , // need foldr
223- |cx, span, subexpr, self_f, other_fs| {
224- // build up a series of `partial_cmp`s from the inside
225- // out (hence foldr) to get lexical ordering, i.e., for op ==
226- // `ast::lt`
227- //
228- // ```
229- // Ordering::then_with(
230- // Option::unwrap_or(
231- // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
232- // ),
233- // Option::unwrap_or(
234- // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
235- // )
236- // )
237- // == Ordering::Less
238- // ```
239- //
240- // and for op ==
241- // `ast::le`
242- //
243- // ```
244- // Ordering::then_with(
245- // Option::unwrap_or(
246- // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
247- // ),
248- // Option::unwrap_or(
249- // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
250- // )
251- // )
252- // != Ordering::Greater
253- // ```
254- //
255- // The optimiser should remove the redundancy. We explicitly
256- // get use the binops to avoid auto-deref dereferencing too many
257- // layers of pointers, if the type includes pointers.
258-
259- // `Option::unwrap_or(PartialOrd::partial_cmp(self.fi, other.fi), Ordering::Equal)`
260- let par_cmp = par_cmp ( cx, span, self_f, other_fs, "Equal" ) ;
261-
262- // `Ordering::then_with(Option::unwrap_or(..), ..)`
263- let then_with_path = cx. expr_path (
264- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , sym:: then_with] ) ) ,
265- ) ;
266- cx. expr_call ( span, then_with_path, vec ! [ par_cmp, cx. lambda0( span, subexpr) ] )
267- } ,
268- |cx, args| match args {
269- Some ( ( span, self_f, other_fs) ) => {
270- let opposite = if less { "Greater" } else { "Less" } ;
271- par_cmp ( cx, span, self_f, other_fs, opposite)
272- }
273- None => cx. expr_bool ( span, inclusive) ,
274- } ,
275- Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
276- if self_args. len ( ) != 2 {
277- cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
278- } else {
279- let op = match ( less, inclusive) {
280- ( false , false ) => GtOp ,
281- ( false , true ) => GeOp ,
282- ( true , false ) => LtOp ,
283- ( true , true ) => LeOp ,
284- } ;
285- some_ordering_collapsed ( cx, span, op, tag_tuple)
286- }
287- } ) ,
288- cx,
289- span,
290- substr,
291- ) ;
292-
293- match * substr. fields {
294- EnumMatching ( .., ref all_fields) | Struct ( .., ref all_fields) if !all_fields. is_empty ( ) => {
295- let ordering = ordering_path ( cx, if less ^ inclusive { "Less" } else { "Greater" } ) ;
296- let comp_op = if inclusive { BinOpKind :: Ne } else { BinOpKind :: Eq } ;
297-
298- cx. expr_binary ( span, comp_op, fold, ordering)
299- }
300- _ => fold,
301- }
302- }
0 commit comments