about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2022-05-16 10:00:32 -0400
committerJason Newcomb <jsnewcomb@pm.me>2022-05-16 10:00:32 -0400
commitc649d4e8a7c4aa951cdf0d4db4bf71fb2f52eee7 (patch)
treedea58b5332bfe22d35fd03601a1db1ceeae51536
parenta1632fffc13b35be1b58b24edabed9cada06b160 (diff)
downloadrust-c649d4e8a7c4aa951cdf0d4db4bf71fb2f52eee7.tar.gz
rust-c649d4e8a7c4aa951cdf0d4db4bf71fb2f52eee7.zip
Fix ICE in `let_unit_value` when calling a static or const callable type
-rw-r--r--clippy_lints/src/unit_types/let_unit_value.rs17
-rw-r--r--tests/ui/crashes/ice-8821.rs8
-rw-r--r--tests/ui/crashes/ice-8821.stderr10
3 files changed, 29 insertions, 6 deletions
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index f3f1f53aac5..d86002c926e 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -3,6 +3,7 @@ use clippy_utils::source::snippet_with_macro_callsite;
 use clippy_utils::visitors::for_each_value_source;
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -71,14 +72,18 @@ fn needs_inferred_result_ty(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
                 ..
             },
             _,
-        ) => cx.qpath_res(path, *hir_id).opt_def_id(),
-        ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(e.hir_id),
+        ) => match cx.qpath_res(path, *hir_id) {
+            Res::Def(DefKind::AssocFn | DefKind::Fn, id) => id,
+            _ => return false,
+        },
+        ExprKind::MethodCall(..) => match cx.typeck_results().type_dependent_def_id(e.hir_id) {
+            Some(id) => id,
+            None => return false,
+        },
         _ => return false,
     };
-    if let Some(id) = id
-        && let sig = cx.tcx.fn_sig(id).skip_binder()
-        && let ty::Param(output_ty) = *sig.output().kind()
-    {
+    let sig = cx.tcx.fn_sig(id).skip_binder();
+    if let ty::Param(output_ty) = *sig.output().kind() {
         sig.inputs().iter().all(|&ty| !ty_contains_param(ty, output_ty.index))
     } else {
         false
diff --git a/tests/ui/crashes/ice-8821.rs b/tests/ui/crashes/ice-8821.rs
new file mode 100644
index 00000000000..fb87b79aeed
--- /dev/null
+++ b/tests/ui/crashes/ice-8821.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::let_unit_value)]
+
+fn f() {}
+static FN: fn() = f;
+
+fn main() {
+    let _: () = FN();
+}
diff --git a/tests/ui/crashes/ice-8821.stderr b/tests/ui/crashes/ice-8821.stderr
new file mode 100644
index 00000000000..486096e0a06
--- /dev/null
+++ b/tests/ui/crashes/ice-8821.stderr
@@ -0,0 +1,10 @@
+error: this let-binding has unit value
+  --> $DIR/ice-8821.rs:7:5
+   |
+LL |     let _: () = FN();
+   |     ^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `FN();`
+   |
+   = note: `-D clippy::let-unit-value` implied by `-D warnings`
+
+error: aborting due to previous error
+