about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/no_effect.rs11
-rw-r--r--tests/ui/no_effect.rs35
-rw-r--r--tests/ui/no_effect.stderr60
3 files changed, 73 insertions, 33 deletions
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs
index 31134743d02..cd54de3ee4b 100644
--- a/clippy_lints/src/no_effect.rs
+++ b/clippy_lints/src/no_effect.rs
@@ -133,9 +133,12 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         },
         ExprKind::Call(callee, args) => {
             if let ExprKind::Path(ref qpath) = callee.kind {
-                let res = cx.qpath_res(qpath, callee.hir_id);
+                if cx.typeck_results().type_dependent_def(expr.hir_id).is_some() {
+                    // type-dependent function call like `impl FnOnce for X`
+                    return false;
+                }
                 let def_matched = matches!(
-                    res,
+                    cx.qpath_res(qpath, callee.hir_id),
                     Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)
                 );
                 if def_matched || is_range_literal(expr) {
@@ -238,6 +241,10 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
         },
         ExprKind::Call(callee, args) => {
             if let ExprKind::Path(ref qpath) = callee.kind {
+                if cx.typeck_results().type_dependent_def(expr.hir_id).is_some() {
+                    // type-dependent function call like `impl FnOnce for X`
+                    return None;
+                }
                 let res = cx.qpath_res(qpath, callee.hir_id);
                 match res {
                     Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)
diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs
index 7bcc4cad0d3..5427c88faf3 100644
--- a/tests/ui/no_effect.rs
+++ b/tests/ui/no_effect.rs
@@ -1,4 +1,4 @@
-#![feature(box_syntax)]
+#![feature(box_syntax, fn_traits, unboxed_closures)]
 #![warn(clippy::no_effect_underscore_binding)]
 #![allow(dead_code)]
 #![allow(path_statements)]
@@ -58,6 +58,36 @@ unsafe fn unsafe_fn() -> i32 {
     0
 }
 
+struct GreetStruct1;
+
+impl FnOnce<(&str,)> for GreetStruct1 {
+    type Output = ();
+
+    extern "rust-call" fn call_once(self, (who,): (&str,)) -> Self::Output {
+        println!("hello {}", who);
+    }
+}
+
+struct GreetStruct2();
+
+impl FnOnce<(&str,)> for GreetStruct2 {
+    type Output = ();
+
+    extern "rust-call" fn call_once(self, (who,): (&str,)) -> Self::Output {
+        println!("hello {}", who);
+    }
+}
+
+struct GreetStruct3 {}
+
+impl FnOnce<(&str,)> for GreetStruct3 {
+    type Output = ();
+
+    extern "rust-call" fn call_once(self, (who,): (&str,)) -> Self::Output {
+        println!("hello {}", who);
+    }
+}
+
 fn main() {
     let s = get_struct();
     let s2 = get_struct();
@@ -108,4 +138,7 @@ fn main() {
     DropTuple(0);
     DropEnum::Tuple(0);
     DropEnum::Struct { field: 0 };
+    GreetStruct1("world");
+    GreetStruct2()("world");
+    GreetStruct3 {}("world");
 }
diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr
index a5dbc9fef45..06b88bb5bee 100644
--- a/tests/ui/no_effect.stderr
+++ b/tests/ui/no_effect.stderr
@@ -1,5 +1,5 @@
 error: statement with no effect
-  --> $DIR/no_effect.rs:65:5
+  --> $DIR/no_effect.rs:95:5
    |
 LL |     0;
    |     ^^
@@ -7,157 +7,157 @@ LL |     0;
    = note: `-D clippy::no-effect` implied by `-D warnings`
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:66:5
+  --> $DIR/no_effect.rs:96:5
    |
 LL |     s2;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:67:5
+  --> $DIR/no_effect.rs:97:5
    |
 LL |     Unit;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:68:5
+  --> $DIR/no_effect.rs:98:5
    |
 LL |     Tuple(0);
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:69:5
+  --> $DIR/no_effect.rs:99:5
    |
 LL |     Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:70:5
+  --> $DIR/no_effect.rs:100:5
    |
 LL |     Struct { ..s };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:71:5
+  --> $DIR/no_effect.rs:101:5
    |
 LL |     Union { a: 0 };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:72:5
+  --> $DIR/no_effect.rs:102:5
    |
 LL |     Enum::Tuple(0);
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:73:5
+  --> $DIR/no_effect.rs:103:5
    |
 LL |     Enum::Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:74:5
+  --> $DIR/no_effect.rs:104:5
    |
 LL |     5 + 6;
    |     ^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:75:5
+  --> $DIR/no_effect.rs:105:5
    |
 LL |     *&42;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:76:5
+  --> $DIR/no_effect.rs:106:5
    |
 LL |     &6;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:77:5
+  --> $DIR/no_effect.rs:107:5
    |
 LL |     (5, 6, 7);
    |     ^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:78:5
+  --> $DIR/no_effect.rs:108:5
    |
 LL |     box 42;
    |     ^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:79:5
+  --> $DIR/no_effect.rs:109:5
    |
 LL |     ..;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:80:5
+  --> $DIR/no_effect.rs:110:5
    |
 LL |     5..;
    |     ^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:81:5
+  --> $DIR/no_effect.rs:111:5
    |
 LL |     ..5;
    |     ^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:82:5
+  --> $DIR/no_effect.rs:112:5
    |
 LL |     5..6;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:83:5
+  --> $DIR/no_effect.rs:113:5
    |
 LL |     5..=6;
    |     ^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:84:5
+  --> $DIR/no_effect.rs:114:5
    |
 LL |     [42, 55];
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:85:5
+  --> $DIR/no_effect.rs:115:5
    |
 LL |     [42, 55][1];
    |     ^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:86:5
+  --> $DIR/no_effect.rs:116:5
    |
 LL |     (42, 55).1;
    |     ^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:87:5
+  --> $DIR/no_effect.rs:117:5
    |
 LL |     [42; 55];
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:88:5
+  --> $DIR/no_effect.rs:118:5
    |
 LL |     [42; 55][13];
    |     ^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:90:5
+  --> $DIR/no_effect.rs:120:5
    |
 LL |     || x += 5;
    |     ^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:92:5
+  --> $DIR/no_effect.rs:122:5
    |
 LL |     FooString { s: s };
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:93:5
+  --> $DIR/no_effect.rs:123:5
    |
 LL |     let _unused = 1;
    |     ^^^^^^^^^^^^^^^^
@@ -165,19 +165,19 @@ LL |     let _unused = 1;
    = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:94:5
+  --> $DIR/no_effect.rs:124:5
    |
 LL |     let _penguin = || println!("Some helpful closure");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:95:5
+  --> $DIR/no_effect.rs:125:5
    |
 LL |     let _duck = Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:96:5
+  --> $DIR/no_effect.rs:126:5
    |
 LL |     let _cat = [2, 4, 6, 8][2];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^