]> git.lizzy.rs Git - rust.git/commitdiff
Only return DefIds to Fn-like definitions in clippy_utils::fn_def_id
authorAlex Macleod <alex@macleod.io>
Thu, 26 May 2022 14:21:09 +0000 (14:21 +0000)
committerAlex Macleod <alex@macleod.io>
Thu, 26 May 2022 14:35:19 +0000 (14:35 +0000)
clippy_utils/src/lib.rs
tests/ui/crashes/ice-8850.rs [new file with mode: 0644]
tests/ui/crashes/ice-8850.stderr [new file with mode: 0644]

index adb37cc9d7510bd1d9a58d5fccbdbd8af75c52d2..b8a80d4adc31b99b47aed1bccb1f78901577779a 100644 (file)
@@ -1916,7 +1916,17 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
                 ..
             },
             ..,
-        ) => cx.typeck_results().qpath_res(qpath, *path_hir_id).opt_def_id(),
+        ) => {
+            // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or
+            // deref to fn pointers, dyn Fn, impl Fn - #8850
+            if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =
+                cx.typeck_results().qpath_res(qpath, *path_hir_id)
+            {
+                Some(id)
+            } else {
+                None
+            }
+        },
         _ => None,
     }
 }
diff --git a/tests/ui/crashes/ice-8850.rs b/tests/ui/crashes/ice-8850.rs
new file mode 100644 (file)
index 0000000..f2747ab
--- /dev/null
@@ -0,0 +1,27 @@
+fn fn_pointer_static() -> usize {
+    static FN: fn() -> usize = || 1;
+    let res = FN() + 1;
+    res
+}
+
+fn fn_pointer_const() -> usize {
+    const FN: fn() -> usize = || 1;
+    let res = FN() + 1;
+    res
+}
+
+fn deref_to_dyn_fn() -> usize {
+    struct Derefs;
+    impl std::ops::Deref for Derefs {
+        type Target = dyn Fn() -> usize;
+
+        fn deref(&self) -> &Self::Target {
+            &|| 2
+        }
+    }
+    static FN: Derefs = Derefs;
+    let res = FN() + 1;
+    res
+}
+
+fn main() {}
diff --git a/tests/ui/crashes/ice-8850.stderr b/tests/ui/crashes/ice-8850.stderr
new file mode 100644 (file)
index 0000000..620fd1e
--- /dev/null
@@ -0,0 +1,45 @@
+error: returning the result of a `let` binding from a block
+  --> $DIR/ice-8850.rs:4:5
+   |
+LL |     let res = FN() + 1;
+   |     ------------------- unnecessary `let` binding
+LL |     res
+   |     ^^^
+   |
+   = note: `-D clippy::let-and-return` implied by `-D warnings`
+help: return the expression directly
+   |
+LL ~     
+LL ~     FN() + 1
+   |
+
+error: returning the result of a `let` binding from a block
+  --> $DIR/ice-8850.rs:10:5
+   |
+LL |     let res = FN() + 1;
+   |     ------------------- unnecessary `let` binding
+LL |     res
+   |     ^^^
+   |
+help: return the expression directly
+   |
+LL ~     
+LL ~     FN() + 1
+   |
+
+error: returning the result of a `let` binding from a block
+  --> $DIR/ice-8850.rs:24:5
+   |
+LL |     let res = FN() + 1;
+   |     ------------------- unnecessary `let` binding
+LL |     res
+   |     ^^^
+   |
+help: return the expression directly
+   |
+LL ~     
+LL ~     FN() + 1
+   |
+
+error: aborting due to 3 previous errors
+