]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax_ext/deriving/cmp/partial_ord.rs
Auto merge of #35856 - phimuemue:master, r=brson
[rust.git] / src / libsyntax_ext / deriving / cmp / partial_ord.rs
index 26c14ae934f72796e58c20b6727d04603ff50bdc..99d60c43c5457deec8b75c111a56a83acb0d5233 100644 (file)
@@ -13,8 +13,8 @@
 use deriving::generic::*;
 use deriving::generic::ty::*;
 
-use syntax::ast::{MetaItem, Expr, BinOpKind, self};
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ast::{self, BinOpKind, Expr, MetaItem};
+use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
 use syntax::parse::token::InternedString;
 use syntax::ptr::P;
@@ -24,8 +24,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
                                    span: Span,
                                    mitem: &MetaItem,
                                    item: &Annotatable,
-                                   push: &mut FnMut(Annotatable))
-{
+                                   push: &mut FnMut(Annotatable)) {
     macro_rules! md {
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
@@ -53,7 +52,7 @@ macro_rules! md {
                                     true));
 
     let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+    let attrs = vec![cx.attribute(span, inline)];
 
     let partial_cmp_def = MethodDef {
         name: "partial_cmp",
@@ -66,7 +65,7 @@ macro_rules! md {
         unify_fieldless_variants: true,
         combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
             cs_partial_cmp(cx, span, substr)
-        }))
+        })),
     };
 
     // avoid defining extra methods if we can
@@ -75,13 +74,11 @@ macro_rules! md {
     let methods = if is_type_without_fields(item) {
         vec![partial_cmp_def]
     } else {
-        vec![
-            partial_cmp_def,
-            md!("lt", true, false),
-            md!("le", true, true),
-            md!("gt", false, false),
-            md!("ge", false, true)
-        ]
+        vec![partial_cmp_def,
+             md!("lt", true, false),
+             md!("le", true, true),
+             md!("gt", false, false),
+             md!("ge", false, true)]
     };
 
     let trait_def = TraitDef {
@@ -91,6 +88,7 @@ macro_rules! md {
         additional_bounds: vec![],
         generics: LifetimeBounds::empty(),
         is_unsafe: false,
+        supports_unions: false,
         methods: methods,
         associated_types: Vec::new(),
     };
@@ -99,142 +97,146 @@ macro_rules! md {
 
 #[derive(Copy, Clone)]
 pub enum OrderingOp {
-    PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
+    PartialCmpOp,
+    LtOp,
+    LeOp,
+    GtOp,
+    GeOp,
 }
 
 pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
                                span: Span,
                                op: OrderingOp,
-                               self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
+                               self_arg_tags: &[ast::Ident])
+                               -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
     let op_str = match op {
         PartialCmpOp => "partial_cmp",
-        LtOp => "lt", LeOp => "le",
-        GtOp => "gt", GeOp => "ge",
+        LtOp => "lt",
+        LeOp => "le",
+        GtOp => "gt",
+        GeOp => "ge",
     };
     cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
 }
 
-pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
-              substr: &Substructure) -> P<Expr> {
+pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__cmp");
-    let ordering = cx.path_global(span,
-                                  cx.std_path(&["cmp", "Ordering", "Equal"]));
+    let ordering = cx.path_global(span, cx.std_path(&["cmp", "Ordering", "Equal"]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
 
     let partial_cmp_path = cx.std_path(&["cmp", "PartialOrd", "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) => {
-                    ...
-                }
-                __cmp => __cmp
-            },
-        __cmp => __cmp
-    }
-    */
-    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 = match (other_fs.len(), other_fs.get(0)) {
-                    (1, Some(o_f)) => o_f,
-                    _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
-                };
-
-                let args = vec![
+    // 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) => {
+    // ...
+    // }
+    // __cmp => __cmp
+    // },
+    // __cmp => __cmp
+    // }
+    //
+    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 = match (other_fs.len(), other_fs.get(0)) {
+                (1, Some(o_f)) => o_f,
+                _ => 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,
-                                vec![cx.pat_some(span,
-                                                 cx.pat_enum(span,
-                                                             ordering.clone(),
-                                                             vec![]))],
-                                old);
-            let neq_arm = cx.arm(span,
-                                 vec![cx.pat_ident(span, test_id)],
-                                 cx.expr_ident(span, test_id));
-
-            cx.expr_match(span, new, vec![eq_arm, neq_arm])
-        },
-        equals_expr.clone(),
-        Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
-            if self_args.len() != 2 {
-                cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
-            } else {
-                some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
-            }
-        }),
-        cx, span, substr)
+            cx.expr_call_global(span, partial_cmp_path.clone(), args)
+        };
+
+        let eq_arm = cx.arm(span,
+                            vec![cx.pat_some(span, cx.pat_path(span, ordering.clone()))],
+                            old);
+        let neq_arm = cx.arm(span,
+                             vec![cx.pat_ident(span, test_id)],
+                             cx.expr_ident(span, test_id));
+
+        cx.expr_match(span, new, vec![eq_arm, neq_arm])
+    },
+            equals_expr.clone(),
+            Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+        if self_args.len() != 2 {
+            cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+        } else {
+            some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
+        }
+    }),
+            cx,
+            span,
+            substr)
 }
 
 /// Strict inequality.
-fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
-         span: Span, substr: &Substructure) -> P<Expr> {
+fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
     let op = if less { BinOpKind::Lt } else { BinOpKind::Gt };
-    cs_fold(
-        false, // need foldr,
-        |cx, span, subexpr, self_f, other_fs| {
-            /*
-            build up a series of chain ||'s and &&'s from the inside
-            out (hence foldr) to get lexical ordering, i.e. for op ==
-            `ast::lt`
-
-            ```
-            self.f1 < other.f1 || (!(other.f1 < self.f1) &&
-                (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
-                    (false)
-                ))
-            )
-            ```
-
-            The optimiser should remove the redundancy. We explicitly
-            get use the binops to avoid auto-deref dereferencing too many
-            layers of pointers, if the type includes pointers.
-            */
-            let other_f = match (other_fs.len(), other_fs.get(0)) {
-                (1, Some(o_f)) => o_f,
-                _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+    cs_fold(false, // need foldr,
+            |cx, span, subexpr, self_f, other_fs| {
+        // build up a series of chain ||'s and &&'s from the inside
+        // out (hence foldr) to get lexical ordering, i.e. for op ==
+        // `ast::lt`
+        //
+        // ```
+        // self.f1 < other.f1 || (!(other.f1 < self.f1) &&
+        // (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
+        // (false)
+        // ))
+        // )
+        // ```
+        //
+        // The optimiser should remove the redundancy. We explicitly
+        // get use the binops to avoid auto-deref dereferencing too many
+        // layers of pointers, if the type includes pointers.
+        //
+        let other_f = match (other_fs.len(), other_fs.get(0)) {
+            (1, Some(o_f)) => o_f,
+            _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
+        };
+
+        let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
+
+        let not_cmp = cx.expr_unary(span,
+                                    ast::UnOp::Not,
+                                    cx.expr_binary(span, op, other_f.clone(), self_f));
+
+        let and = cx.expr_binary(span, BinOpKind::And, not_cmp, subexpr);
+        cx.expr_binary(span, BinOpKind::Or, cmp, and)
+    },
+            cx.expr_bool(span, equal),
+            Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+        if self_args.len() != 2 {
+            cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+        } else {
+            let op = match (less, equal) {
+                (true, true) => LeOp,
+                (true, false) => LtOp,
+                (false, true) => GeOp,
+                (false, false) => GtOp,
             };
-
-            let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
-
-            let not_cmp = cx.expr_unary(span, ast::UnOp::Not,
-                                        cx.expr_binary(span, op, other_f.clone(), self_f));
-
-            let and = cx.expr_binary(span, BinOpKind::And, not_cmp, subexpr);
-            cx.expr_binary(span, BinOpKind::Or, cmp, and)
-        },
-        cx.expr_bool(span, equal),
-        Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
-            if self_args.len() != 2 {
-                cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
-            } else {
-                let op = match (less, equal) {
-                    (true,  true) => LeOp, (true,  false) => LtOp,
-                    (false, true) => GeOp, (false, false) => GtOp,
-                };
-                some_ordering_collapsed(cx, span, op, tag_tuple)
-            }
-        }),
-        cx, span, substr)
+            some_ordering_collapsed(cx, span, op, tag_tuple)
+        }
+    }),
+            cx,
+            span,
+            substr)
 }