about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-06-22 15:00:53 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2022-06-27 08:14:09 +1000
commit00207ead61ecff9dba4e61e5828fd6a32330f6c0 (patch)
treeae58daa40094ff542088df8819bc8e43e03de329
parentea74997c414779d5628b2a6a8a964582b20607c8 (diff)
downloadrust-00207ead61ecff9dba4e61e5828fd6a32330f6c0.tar.gz
rust-00207ead61ecff9dba4e61e5828fd6a32330f6c0.zip
Improve derived discriminant testing.
Currently the generated code for methods like `eq`, `ne`, and `partial_cmp`
includes stuff like this:
```
let __self_vi = ::core::intrinsics::discriminant_value(&*self);
let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
if true && __self_vi == __arg_1_vi {
    ...
}
```
This commit removes the unnecessary `true &&`, and makes the generating
code a little easier to read in the process. It also fixes some errors
in comments.
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs37
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout22
2 files changed, 27 insertions, 32 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 53369afae27..8760845138e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -1392,37 +1392,32 @@ impl<'a> MethodDef<'a> {
             //
             // i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
             // with three Self args, builds three statements:
-            //
             // ```
-            // let __self0_vi = std::intrinsics::discriminant_value(&self);
-            // let __self1_vi = std::intrinsics::discriminant_value(&arg1);
-            // let __self2_vi = std::intrinsics::discriminant_value(&arg2);
+            // let __self_vi = std::intrinsics::discriminant_value(&self);
+            // let __arg_1_vi = std::intrinsics::discriminant_value(&arg1);
+            // let __arg_2_vi = std::intrinsics::discriminant_value(&arg2);
             // ```
             let mut index_let_stmts: Vec<ast::Stmt> = Vec::with_capacity(vi_idents.len() + 1);
 
-            // We also build an expression which checks whether all discriminants are equal
-            // discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
+            // We also build an expression which checks whether all discriminants are equal:
+            // `__self_vi == __arg_1_vi && __self_vi == __arg_2_vi && ...`
             let mut discriminant_test = cx.expr_bool(span, true);
-
-            let mut first_ident = None;
-            for (&ident, self_arg) in iter::zip(&vi_idents, &self_args) {
+            for (i, (&ident, self_arg)) in iter::zip(&vi_idents, &self_args).enumerate() {
                 let self_addr = cx.expr_addr_of(span, self_arg.clone());
                 let variant_value =
                     deriving::call_intrinsic(cx, span, sym::discriminant_value, vec![self_addr]);
                 let let_stmt = cx.stmt_let(span, false, ident, variant_value);
                 index_let_stmts.push(let_stmt);
 
-                match first_ident {
-                    Some(first) => {
-                        let first_expr = cx.expr_ident(span, first);
-                        let id = cx.expr_ident(span, ident);
-                        let test = cx.expr_binary(span, BinOpKind::Eq, first_expr, id);
-                        discriminant_test =
-                            cx.expr_binary(span, BinOpKind::And, discriminant_test, test)
-                    }
-                    None => {
-                        first_ident = Some(ident);
-                    }
+                if i > 0 {
+                    let id0 = cx.expr_ident(span, vi_idents[0]);
+                    let id = cx.expr_ident(span, ident);
+                    let test = cx.expr_binary(span, BinOpKind::Eq, id0, id);
+                    discriminant_test = if i == 1 {
+                        test
+                    } else {
+                        cx.expr_binary(span, BinOpKind::And, discriminant_test, test)
+                    };
                 }
             }
 
@@ -1453,7 +1448,7 @@ impl<'a> MethodDef<'a> {
             //      }
             //  }
             //  else {
-            //      <delegated expression referring to __self0_vi, et al.>
+            //      <delegated expression referring to __self_vi, et al.>
             //  }
             let all_match = cx.expr_match(span, match_arg, match_arms);
             let arm_expr = cx.expr_if(span, discriminant_test, all_match, Some(arm_expr));
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
index 88aae2da654..faa5a3c3ddf 100644
--- a/src/test/ui/deriving/deriving-all-codegen.stdout
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -648,7 +648,7 @@ impl ::core::cmp::PartialEq for Fieldless {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) { _ => true, }
                 } else { false }
         }
@@ -672,7 +672,7 @@ impl ::core::cmp::PartialOrd for Fieldless {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         _ =>
                             ::core::option::Option::Some(::core::cmp::Ordering::Equal),
@@ -692,7 +692,7 @@ impl ::core::cmp::Ord for Fieldless {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         _ => ::core::cmp::Ordering::Equal,
                     }
@@ -783,7 +783,7 @@ impl ::core::cmp::PartialEq for Mixed {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
                             (*__self_0) == (*__arg_1_0),
@@ -800,7 +800,7 @@ impl ::core::cmp::PartialEq for Mixed {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
                             (*__self_0) != (*__arg_1_0),
@@ -837,7 +837,7 @@ impl ::core::cmp::PartialOrd for Mixed {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
                             match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
@@ -880,7 +880,7 @@ impl ::core::cmp::Ord for Mixed {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
                             match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
@@ -973,7 +973,7 @@ impl ::core::cmp::PartialEq for Fielded {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
                             (*__self_0) == (*__arg_1_0),
@@ -991,7 +991,7 @@ impl ::core::cmp::PartialEq for Fielded {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
                             (*__self_0) != (*__arg_1_0),
@@ -1029,7 +1029,7 @@ impl ::core::cmp::PartialOrd for Fielded {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
                             match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
@@ -1072,7 +1072,7 @@ impl ::core::cmp::Ord for Fielded {
         {
             let __self_vi = ::core::intrinsics::discriminant_value(&*self);
             let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
-            if true && __self_vi == __arg_1_vi {
+            if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
                             match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {