]> git.lizzy.rs Git - rust.git/commitdiff
Support generic type
authorsinkuu <sinkuupump@gmail.com>
Fri, 17 Feb 2017 10:59:52 +0000 (19:59 +0900)
committersinkuu <sinkuupump@gmail.com>
Sat, 18 Feb 2017 01:14:25 +0000 (10:14 +0900)
clippy_lints/src/assign_ops.rs
clippy_lints/src/methods.rs
clippy_lints/src/misc.rs
clippy_lints/src/new_without_default.rs
clippy_lints/src/should_assert_eq.rs
clippy_lints/src/utils/mod.rs
clippy_lints/src/utils/paths.rs
tests/ui/should_assert_eq.rs
tests/ui/should_assert_eq.stderr

index 71ebb996fc579e86c68f3f91312cda6a66135083..ea3e29cff122fc20760afc0432a235e958dd9e19 100644 (file)
@@ -152,7 +152,7 @@ macro_rules! ops {
                                             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,
                                 }
index b74bd9266a4515edaa6fc548d496ad9db9d03502..9acf4c7e973ac1f4f9e45f95f1d8ac09eabc8b87 100644 (file)
@@ -724,7 +724,7 @@ fn check_unwrap_or_default(
                         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,
     }
 }
index d397d4251117661ae062ddde754f2ce55c3bf72d..d2f794def0cf6f4b727eefc6da0bbcf5c6a8439b 100644 (file)
@@ -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;
     }
 
index e4e98c260388736e90c9387205cacf6b84929f39..ece7e130c5fbeab688638a2b452d3ad7ec877b54 100644 (file)
@@ -115,7 +115,7 @@ fn check_fn(
                     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;
                 }
             }
index 9bacc64f61c03a0ad5904957b38782a6547855c5..16933ea27474f081619b62dfefed064d3823a902 100644 (file)
@@ -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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
                 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");
             }
         }}
index 1211b77ddb87c0a0a4964a14953d0e37f197ded5..ce581febfe41a45689463c0fa25b7930a5c308ee 100644 (file)
@@ -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)
     })
index 6ee35e3bd966bd969922d2ff1b417ecd11737e30..5edff76d9969e277fcb47e71d20be6f1a85a7b2a 100644 (file)
@@ -15,7 +15,6 @@
 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"];
index 41e3a411383369523a5e761f4e4e38b6d1376290..5abf35664259fed009d95de40a54691fbc3c7aa6 100644 (file)
@@ -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
 }
index 3c51dbe0a9c49feb5bd926db1de43b3dd9ca596e..68d287fda8d54f84c123105d6f58afd1c4dd6023 100644 (file)
@@ -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