From 6bb426b0e37d0db4433fc6ffd67e7ffc26d6ab68 Mon Sep 17 00:00:00 2001
From: sinkuu <sinkuupump@gmail.com>
Date: Fri, 17 Feb 2017 17:32:51 +0900
Subject: [PATCH 1/4] Add `should_assert_eq` lint (fixes #641)

---
 clippy_lints/src/lib.rs              |  2 +
 clippy_lints/src/should_assert_eq.rs | 59 ++++++++++++++++++++++++++++
 clippy_lints/src/utils/paths.rs      |  1 +
 tests/ui/float_cmp.rs                |  2 +-
 tests/ui/should_assert_eq.rs         | 16 ++++++++
 tests/ui/should_assert_eq.stderr     | 23 +++++++++++
 6 files changed, 102 insertions(+), 1 deletion(-)
 create mode 100644 clippy_lints/src/should_assert_eq.rs
 create mode 100644 tests/ui/should_assert_eq.rs
 create mode 100644 tests/ui/should_assert_eq.stderr

diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 13ad8b41f96..4f99dff89b4 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -126,6 +126,7 @@ pub mod regex;
 pub mod returns;
 pub mod serde;
 pub mod shadow;
+pub mod should_assert_eq;
 pub mod strings;
 pub mod swap;
 pub mod temporary_assignment;
@@ -297,6 +298,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
     reg.register_early_lint_pass(box double_parens::DoubleParens);
     reg.register_late_lint_pass(box unused_io_amount::UnusedIoAmount);
     reg.register_late_lint_pass(box large_enum_variant::LargeEnumVariant::new(conf.enum_variant_size_threshold));
+    reg.register_late_lint_pass(box should_assert_eq::ShouldAssertEq);
 
     reg.register_lint_group("clippy_restrictions", vec![
         arithmetic::FLOAT_ARITHMETIC,
diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs
new file mode 100644
index 00000000000..9bacc64f61c
--- /dev/null
+++ b/clippy_lints/src/should_assert_eq.rs
@@ -0,0 +1,59 @@
+use rustc::lint::*;
+use rustc::hir::*;
+use utils::{paths, is_direct_expn_of, get_trait_def_id, implements_trait, span_lint};
+
+/// **What it does:** Checks for `assert!(x == y)` which can be written better
+/// as `assert_eq!(x, y)` if `x` and `y` implement `Debug` trait.
+///
+/// **Why is this bad?** `assert_eq` provides better assertion failure reporting.
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```rust
+/// let (x, y) = (1, 2);
+///
+/// assert!(x == y);  // assertion failed: x == y
+/// assert_eq!(x, y); // assertion failed: `(left == right)` (left: `1`, right: `2`)
+/// ```
+declare_lint! {
+    pub SHOULD_ASSERT_EQ,
+    Warn,
+    "using `assert` macro for asserting equality"
+}
+
+pub struct ShouldAssertEq;
+
+impl LintPass for ShouldAssertEq {
+    fn get_lints(&self) -> LintArray {
+        lint_array![SHOULD_ASSERT_EQ]
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ShouldAssertEq {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
+        if_let_chain! {[
+            let ExprIf(ref cond, ..) = e.node,
+            let ExprUnary(UnOp::UnNot, ref cond) = cond.node,
+            let ExprBinary(ref binop, ref expr1, ref expr2) = cond.node,
+        ], {
+            if is_direct_expn_of(cx, e.span, "assert").is_none() {
+                return;
+            }
+
+            if binop.node != BinOp_::BiEq {
+                return;
+            }
+
+            let debug_trait = get_trait_def_id(cx, &paths::DEBUG_TRAIT)
+                .expect("cannot find Debug trait");
+
+            let ty1 = cx.tables.expr_ty(expr1);
+            let ty2 = cx.tables.expr_ty(expr2);
+            if implements_trait(cx, ty1, debug_trait, vec![]) &&
+                implements_trait(cx, ty2, debug_trait, vec![]) {
+                span_lint(cx, SHOULD_ASSERT_EQ, e.span, "use `assert_eq` for better reporting");
+            }
+        }}
+    }
+}
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index 5edff76d996..6ee35e3bd96 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -15,6 +15,7 @@ pub const CMP_MIN: [&'static str; 3] = ["core", "cmp", "min"];
 pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"];
 pub const CSTRING_NEW: [&'static str; 5] = ["std", "ffi", "c_str", "CString", "new"];
 pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Debug", "fmt"];
+pub const DEBUG_TRAIT: [&'static str; 3] = ["core", "fmt", "Debug"];
 pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"];
 pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Display", "fmt"];
 pub const DROP: [&'static str; 3] = ["core", "mem", "drop"];
diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs
index de897caca08..024dd9c242c 100644
--- a/tests/ui/float_cmp.rs
+++ b/tests/ui/float_cmp.rs
@@ -92,5 +92,5 @@ fn main() {
     let a: *const f32 = xs.as_ptr();
     let b: *const f32 = xs.as_ptr();
 
-    assert!(a == b); // no errors
+    assert_eq!(a, b); // no errors
 }
diff --git a/tests/ui/should_assert_eq.rs b/tests/ui/should_assert_eq.rs
new file mode 100644
index 00000000000..41e3a411383
--- /dev/null
+++ b/tests/ui/should_assert_eq.rs
@@ -0,0 +1,16 @@
+#![feature(plugin)]
+#![plugin(clippy)]
+
+#![deny(should_assert_eq)]
+
+#[derive(PartialEq, Eq)]
+struct NonDebug(i32);
+
+#[derive(Debug, PartialEq, Eq)]
+struct Debug(i32);
+
+fn main() {
+    assert!(1 == 2);
+    assert!(Debug(1) == Debug(2));
+    assert!(NonDebug(1) == NonDebug(1)); // ok
+}
diff --git a/tests/ui/should_assert_eq.stderr b/tests/ui/should_assert_eq.stderr
new file mode 100644
index 00000000000..3c51dbe0a9c
--- /dev/null
+++ b/tests/ui/should_assert_eq.stderr
@@ -0,0 +1,23 @@
+error: use `assert_eq` for better reporting
+  --> $DIR/should_assert_eq.rs:13:5
+   |
+13 |     assert!(1 == 2);
+   |     ^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/should_assert_eq.rs:4:9
+   |
+4  | #![deny(should_assert_eq)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro outside of the current crate
+
+error: use `assert_eq` for better reporting
+  --> $DIR/should_assert_eq.rs:14:5
+   |
+14 |     assert!(Debug(1) == Debug(2));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to 2 previous errors
+

From 16e53c9868d2fe3fd8b2bd7b0f77764da689918a Mon Sep 17 00:00:00 2001
From: sinkuu <sinkuupump@gmail.com>
Date: Fri, 17 Feb 2017 17:48:19 +0900
Subject: [PATCH 2/4] Run update_lints.py

---
 CHANGELOG.md            | 1 +
 README.md               | 3 ++-
 clippy_lints/src/lib.rs | 1 +
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 90f67e8aec7..1192195cd6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -423,6 +423,7 @@ All notable changes to this project will be documented in this file.
 [`shadow_same`]: https://github.com/Manishearth/rust-clippy/wiki#shadow_same
 [`shadow_unrelated`]: https://github.com/Manishearth/rust-clippy/wiki#shadow_unrelated
 [`short_circuit_statement`]: https://github.com/Manishearth/rust-clippy/wiki#short_circuit_statement
+[`should_assert_eq`]: https://github.com/Manishearth/rust-clippy/wiki#should_assert_eq
 [`should_implement_trait`]: https://github.com/Manishearth/rust-clippy/wiki#should_implement_trait
 [`similar_names`]: https://github.com/Manishearth/rust-clippy/wiki#similar_names
 [`single_char_pattern`]: https://github.com/Manishearth/rust-clippy/wiki#single_char_pattern
diff --git a/README.md b/README.md
index 9e4b9fba1b6..842e654678b 100644
--- a/README.md
+++ b/README.md
@@ -180,7 +180,7 @@ transparently:
 
 ## Lints
 
-There are 190 lints included in this crate:
+There are 191 lints included in this crate:
 
 name                                                                                                                   | default | triggers on
 -----------------------------------------------------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------
@@ -329,6 +329,7 @@ name
 [shadow_same](https://github.com/Manishearth/rust-clippy/wiki#shadow_same)                                             | allow   | rebinding a name to itself, e.g. `let mut x = &mut x`
 [shadow_unrelated](https://github.com/Manishearth/rust-clippy/wiki#shadow_unrelated)                                   | allow   | rebinding a name without even using the original value
 [short_circuit_statement](https://github.com/Manishearth/rust-clippy/wiki#short_circuit_statement)                     | warn    | using a short circuit boolean condition as a statement
+[should_assert_eq](https://github.com/Manishearth/rust-clippy/wiki#should_assert_eq)                                   | warn    | using `assert` macro for asserting equality
 [should_implement_trait](https://github.com/Manishearth/rust-clippy/wiki#should_implement_trait)                       | warn    | defining a method that should be implementing a std trait
 [similar_names](https://github.com/Manishearth/rust-clippy/wiki#similar_names)                                         | allow   | similarly named items and bindings
 [single_char_pattern](https://github.com/Manishearth/rust-clippy/wiki#single_char_pattern)                             | warn    | using a single-character str where a char could be used, e.g. `_.split("x")`
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 4f99dff89b4..814daf7d645 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -481,6 +481,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         returns::LET_AND_RETURN,
         returns::NEEDLESS_RETURN,
         serde::SERDE_API_MISUSE,
+        should_assert_eq::SHOULD_ASSERT_EQ,
         strings::STRING_LIT_AS_BYTES,
         swap::ALMOST_SWAPPED,
         swap::MANUAL_SWAP,

From 8cb2ec804dced5435aaea7f465eccddcdeddba19 Mon Sep 17 00:00:00 2001
From: sinkuu <sinkuupump@gmail.com>
Date: Fri, 17 Feb 2017 19:59:52 +0900
Subject: [PATCH 3/4] Support generic type

---
 clippy_lints/src/assign_ops.rs          |  2 +-
 clippy_lints/src/methods.rs             |  4 ++--
 clippy_lints/src/misc.rs                |  2 +-
 clippy_lints/src/new_without_default.rs |  4 ++--
 clippy_lints/src/should_assert_eq.rs    | 18 ++++++++++++------
 clippy_lints/src/utils/mod.rs           | 12 +++++++++---
 clippy_lints/src/utils/paths.rs         |  1 -
 tests/ui/should_assert_eq.rs            |  7 +++++++
 tests/ui/should_assert_eq.stderr        | 10 +++++++++-
 9 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs
index 71ebb996fc5..ea3e29cff12 100644
--- a/clippy_lints/src/assign_ops.rs
+++ b/clippy_lints/src/assign_ops.rs
@@ -152,7 +152,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
                                             let hir::Item_::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node,
                                             trait_ref.path.def.def_id() == trait_id
                                         ], { return; }}
-                                        implements_trait($cx, $ty, trait_id, vec![$rty])
+                                        implements_trait($cx, $ty, trait_id, &[$rty], None)
                                     },)*
                                     _ => false,
                                 }
diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs
index b74bd9266a4..9acf4c7e973 100644
--- a/clippy_lints/src/methods.rs
+++ b/clippy_lints/src/methods.rs
@@ -724,7 +724,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
                         return false;
                     };
 
-                    if implements_trait(cx, arg_ty, default_trait_id, Vec::new()) {
+                    if implements_trait(cx, arg_ty, default_trait_id, &[], None) {
                         span_lint_and_then(cx,
                                            OR_FUN_CALL,
                                            span,
@@ -1268,7 +1268,7 @@ fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option<ty::Ty<'a>> {
 /// This checks whether a given type is known to implement Debug.
 fn has_debug_impl<'a, 'b>(ty: ty::Ty<'a>, cx: &LateContext<'b, 'a>) -> bool {
     match cx.tcx.lang_items.debug_trait() {
-        Some(debug) => implements_trait(cx, ty, debug, Vec::new()),
+        Some(debug) => implements_trait(cx, ty, debug, &[], None),
         None => false,
     }
 }
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index d397d425111..d2f794def0c 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -420,7 +420,7 @@ fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: S
         None => return,
     };
 
-    if !implements_trait(cx, arg_ty, partial_eq_trait_id, vec![other_ty]) {
+    if !implements_trait(cx, arg_ty, partial_eq_trait_id, &[other_ty], None) {
         return;
     }
 
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index e4e98c26038..ece7e130c5f 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -115,7 +115,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
                     self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
                     same_tys(cx, self_ty, return_ty(cx, id), id),
                     let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT),
-                    !implements_trait(cx, self_ty, default_trait_id, Vec::new())
+                    !implements_trait(cx, self_ty, default_trait_id, &[], None)
                 ], {
                     if let Some(sp) = can_derive_default(self_ty, cx, default_trait_id) {
                         span_lint_and_then(cx,
@@ -156,7 +156,7 @@ fn can_derive_default<'t, 'c>(ty: ty::Ty<'t>, cx: &LateContext<'c, 't>, default_
         ty::TyAdt(adt_def, substs) if adt_def.is_struct() => {
             for field in adt_def.all_fields() {
                 let f_ty = field.ty(cx.tcx, substs);
-                if !implements_trait(cx, f_ty, default_trait_id, Vec::new()) {
+                if !implements_trait(cx, f_ty, default_trait_id, &[], None) {
                     return None;
                 }
             }
diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs
index 9bacc64f61c..16933ea2747 100644
--- a/clippy_lints/src/should_assert_eq.rs
+++ b/clippy_lints/src/should_assert_eq.rs
@@ -1,13 +1,13 @@
 use rustc::lint::*;
 use rustc::hir::*;
-use utils::{paths, is_direct_expn_of, get_trait_def_id, implements_trait, span_lint};
+use utils::{is_direct_expn_of, implements_trait, span_lint};
 
 /// **What it does:** Checks for `assert!(x == y)` which can be written better
 /// as `assert_eq!(x, y)` if `x` and `y` implement `Debug` trait.
 ///
 /// **Why is this bad?** `assert_eq` provides better assertion failure reporting.
 ///
-/// **Known problems:** None.
+/// **Known problems:** Hopefully none.
 ///
 /// **Example:**
 /// ```rust
@@ -45,13 +45,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ShouldAssertEq {
                 return;
             }
 
-            let debug_trait = get_trait_def_id(cx, &paths::DEBUG_TRAIT)
-                .expect("cannot find Debug trait");
+            let debug_trait = if let Some(t) = cx.tcx.lang_items.debug_trait() {
+                t
+            } else {
+                return;
+            };
 
             let ty1 = cx.tables.expr_ty(expr1);
             let ty2 = cx.tables.expr_ty(expr2);
-            if implements_trait(cx, ty1, debug_trait, vec![]) &&
-                implements_trait(cx, ty2, debug_trait, vec![]) {
+
+            let parent = cx.tcx.hir.get_parent(e.id);
+
+            if implements_trait(cx, ty1, debug_trait, &[], Some(parent)) &&
+                implements_trait(cx, ty2, debug_trait, &[], Some(parent)) {
                 span_lint(cx, SHOULD_ASSERT_EQ, e.span, "use `assert_eq` for better reporting");
             }
         }}
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 1211b77ddb8..ce581febfe4 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -317,13 +317,19 @@ pub fn implements_trait<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     ty: ty::Ty<'tcx>,
     trait_id: DefId,
-    ty_params: Vec<ty::Ty<'tcx>>
+    ty_params: &[ty::Ty<'tcx>],
+    parent_node_id: Option<NodeId>
 ) -> bool {
     cx.tcx.populate_implementations_for_trait_if_necessary(trait_id);
 
     let ty = cx.tcx.erase_regions(&ty);
-    cx.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
-        let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, &ty_params);
+    let mut b = if let Some(id) = parent_node_id {
+        cx.tcx.infer_ctxt(BodyId { node_id: id }, Reveal::All)
+    } else {
+        cx.tcx.infer_ctxt((), Reveal::All)
+    };
+    b.enter(|infcx| {
+        let obligation = cx.tcx.predicate_for_trait_def(traits::ObligationCause::dummy(), trait_id, 0, ty, ty_params);
 
         traits::SelectionContext::new(&infcx).evaluate_obligation_conservatively(&obligation)
     })
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index 6ee35e3bd96..5edff76d996 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -15,7 +15,6 @@ pub const CMP_MIN: [&'static str; 3] = ["core", "cmp", "min"];
 pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"];
 pub const CSTRING_NEW: [&'static str; 5] = ["std", "ffi", "c_str", "CString", "new"];
 pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Debug", "fmt"];
-pub const DEBUG_TRAIT: [&'static str; 3] = ["core", "fmt", "Debug"];
 pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"];
 pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Display", "fmt"];
 pub const DROP: [&'static str; 3] = ["core", "mem", "drop"];
diff --git a/tests/ui/should_assert_eq.rs b/tests/ui/should_assert_eq.rs
index 41e3a411383..5abf3566425 100644
--- a/tests/ui/should_assert_eq.rs
+++ b/tests/ui/should_assert_eq.rs
@@ -13,4 +13,11 @@ fn main() {
     assert!(1 == 2);
     assert!(Debug(1) == Debug(2));
     assert!(NonDebug(1) == NonDebug(1)); // ok
+
+    test_generic(1, 2, 3, 4);
+}
+
+fn test_generic<T: std::fmt::Debug + Eq, U: Eq>(x: T, y: T, z: U, w: U) {
+    assert!(x == y);
+    assert!(z == w); // ok
 }
diff --git a/tests/ui/should_assert_eq.stderr b/tests/ui/should_assert_eq.stderr
index 3c51dbe0a9c..68d287fda8d 100644
--- a/tests/ui/should_assert_eq.stderr
+++ b/tests/ui/should_assert_eq.stderr
@@ -19,5 +19,13 @@ error: use `assert_eq` for better reporting
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: use `assert_eq` for better reporting
+  --> $DIR/should_assert_eq.rs:21:5
+   |
+21 |     assert!(x == y);
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to 3 previous errors
 

From d2b9b7ece2714170fae43ff9c5c5c3853d04ecef Mon Sep 17 00:00:00 2001
From: sinkuu <sinkuupump@gmail.com>
Date: Fri, 17 Feb 2017 22:37:32 +0900
Subject: [PATCH 4/4] Fix language & if_let_chain usage

---
 clippy_lints/src/should_assert_eq.rs | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/clippy_lints/src/should_assert_eq.rs b/clippy_lints/src/should_assert_eq.rs
index 16933ea2747..e6296154126 100644
--- a/clippy_lints/src/should_assert_eq.rs
+++ b/clippy_lints/src/should_assert_eq.rs
@@ -2,7 +2,7 @@ use rustc::lint::*;
 use rustc::hir::*;
 use utils::{is_direct_expn_of, implements_trait, span_lint};
 
-/// **What it does:** Checks for `assert!(x == y)` which can be written better
+/// **What it does:** Checks for `assert!(x == y)` which can be better written
 /// as `assert_eq!(x, y)` if `x` and `y` implement `Debug` trait.
 ///
 /// **Why is this bad?** `assert_eq` provides better assertion failure reporting.
@@ -36,21 +36,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ShouldAssertEq {
             let ExprIf(ref cond, ..) = e.node,
             let ExprUnary(UnOp::UnNot, ref cond) = cond.node,
             let ExprBinary(ref binop, ref expr1, ref expr2) = cond.node,
+            binop.node == BinOp_::BiEq,
+            is_direct_expn_of(cx, e.span, "assert").is_some(),
+            let Some(debug_trait) = cx.tcx.lang_items.debug_trait(),
         ], {
-            if is_direct_expn_of(cx, e.span, "assert").is_none() {
-                return;
-            }
-
-            if binop.node != BinOp_::BiEq {
-                return;
-            }
-
-            let debug_trait = if let Some(t) = cx.tcx.lang_items.debug_trait() {
-                t
-            } else {
-                return;
-            };
-
             let ty1 = cx.tables.expr_ty(expr1);
             let ty2 = cx.tables.expr_ty(expr2);