]> git.lizzy.rs Git - rust.git/commitdiff
new_ret_no_self added positive test cases
authorJosh Mcguigan <joshmcg88@gmail.com>
Wed, 3 Oct 2018 03:11:56 +0000 (20:11 -0700)
committerJosh Mcguigan <joshmcg88@gmail.com>
Sat, 13 Oct 2018 13:20:39 +0000 (06:20 -0700)
clippy_lints/src/methods/mod.rs
tests/ui/new_ret_no_self.rs [new file with mode: 0644]

index 7c15eb677cc6f74d14b2a7da6e1a357116d02e82..d11dbf0e773c8b7fbb46d726cff28858235acdc5 100644 (file)
@@ -878,6 +878,8 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
         let name = implitem.ident.name;
         let parent = cx.tcx.hir.get_parent(implitem.id);
         let item = cx.tcx.hir.expect_item(parent);
+        let def_id = cx.tcx.hir.local_def_id(item.id);
+        let ty = cx.tcx.type_of(def_id);
         if_chain! {
             if let hir::ImplItemKind::Method(ref sig, id) = implitem.node;
             if let Some(first_arg_ty) = sig.decl.inputs.get(0);
@@ -899,8 +901,6 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
                 }
 
                 // check conventions w.r.t. conversion method names and predicates
-                let def_id = cx.tcx.hir.local_def_id(item.id);
-                let ty = cx.tcx.type_of(def_id);
                 let is_copy = is_copy(cx, ty);
                 for &(ref conv, self_kinds) in &CONVENTIONS {
                     if conv.check(&name.as_str()) {
@@ -928,17 +928,17 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
                         break;
                     }
                 }
-
-                let ret_ty = return_ty(cx, implitem.id);
-                if name == "new" &&
-                   !ret_ty.walk().any(|t| same_tys(cx, t, ty)) {
-                    span_lint(cx,
-                              NEW_RET_NO_SELF,
-                              implitem.span,
-                              "methods called `new` usually return `Self`");
-                }
             }
         }
+
+        let ret_ty = return_ty(cx, implitem.id);
+        if name == "new" &&
+            !ret_ty.walk().any(|t| same_tys(cx, t, ty)) {
+            span_lint(cx,
+                      NEW_RET_NO_SELF,
+                      implitem.span,
+                      "methods called `new` usually return `Self`");
+        }
     }
 }
 
diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs
new file mode 100644 (file)
index 0000000..67933f0
--- /dev/null
@@ -0,0 +1,63 @@
+#![feature(tool_lints)]
+
+#![warn(clippy::new_ret_no_self)]
+#![allow(dead_code, clippy::trivially_copy_pass_by_ref)]
+
+fn main(){}
+
+//trait R {
+//    type Item;
+//}
+//
+//struct S;
+//
+//impl R for S {
+//    type Item = Self;
+//}
+//
+//impl S {
+//    // should not trigger the lint
+//    pub fn new() -> impl R<Item = Self> {
+//        S
+//    }
+//}
+//
+//struct S2;
+//
+//impl R for S2 {
+//    type Item = Self;
+//}
+//
+//impl S2 {
+//    // should not trigger the lint
+//    pub fn new(_: String) -> impl R<Item = Self> {
+//        S2
+//    }
+//}
+//
+//struct T;
+//
+//impl T {
+//    // should not trigger lint
+//    pub fn new() -> Self {
+//        unimplemented!();
+//    }
+//}
+
+struct U;
+
+impl U {
+    // should trigger lint
+    pub fn new() -> u32 {
+        unimplemented!();
+    }
+}
+
+struct V;
+
+impl V {
+    // should trigger lint
+    pub fn new(_: String) -> u32 {
+        unimplemented!();
+    }
+}