From 00207ead61ecff9dba4e61e5828fd6a32330f6c0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Jun 2022 15:00:53 +1000 Subject: [PATCH] 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. --- .../src/deriving/generic/mod.rs | 37 ++++++++----------- .../ui/deriving/deriving-all-codegen.stdout | 22 +++++------ 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 { 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 = 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 { - // + // // } 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)) {