about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKamal Ahmad <kamalahmad22@pm.me>2025-07-14 18:29:30 +0500
committerKamal Ahmad <kamalahmad22@pm.me>2025-07-14 18:57:15 +0500
commitfcd064da752e854258ae30e71c4969ea69490add (patch)
tree0ff316c3a0a85aefd7e5a3adb53af451f00bddef
parent07e2d96effb36dc12c76c445448801d0035a21d0 (diff)
downloadrust-fcd064da752e854258ae30e71c4969ea69490add.tar.gz
rust-fcd064da752e854258ae30e71c4969ea69490add.zip
expect_fun_call: only lint const fn's if they're not inside a const context
-rw-r--r--clippy_lints/src/methods/expect_fun_call.rs20
-rw-r--r--tests/ui/expect_fun_call.fixed9
-rw-r--r--tests/ui/expect_fun_call.rs7
-rw-r--r--tests/ui/expect_fun_call.stderr16
4 files changed, 43 insertions, 9 deletions
diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs
index 896d4397ee6..6e5da5bda8c 100644
--- a/clippy_lints/src/methods/expect_fun_call.rs
+++ b/clippy_lints/src/methods/expect_fun_call.rs
@@ -1,15 +1,16 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::eager_or_lazy::switch_to_lazy_eval;
 use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
-use clippy_utils::{contains_return, peel_blocks};
+use clippy_utils::visitors::for_each_expr;
+use clippy_utils::{contains_return, is_inside_always_const_context, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
 use std::borrow::Cow;
+use std::ops::ControlFlow;
 
 use super::EXPECT_FUN_CALL;
 
@@ -48,10 +49,23 @@ pub(super) fn check<'tcx>(
         arg_root
     }
 
+    fn contains_call<'a>(cx: &LateContext<'a>, arg: &'a hir::Expr<'a>) -> bool {
+        for_each_expr(cx, arg, |expr| {
+            if matches!(expr.kind, hir::ExprKind::MethodCall { .. } | hir::ExprKind::Call { .. })
+                && !is_inside_always_const_context(cx.tcx, expr.hir_id)
+            {
+                ControlFlow::Break(())
+            } else {
+                ControlFlow::Continue(())
+            }
+        })
+        .is_some()
+    }
+
     if name == sym::expect
         && let [arg] = args
         && let arg_root = get_arg_root(cx, arg)
-        && switch_to_lazy_eval(cx, arg_root)
+        && contains_call(cx, arg_root)
         && !contains_return(arg_root)
     {
         let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
diff --git a/tests/ui/expect_fun_call.fixed b/tests/ui/expect_fun_call.fixed
index 0d815ace7b3..b923521afde 100644
--- a/tests/ui/expect_fun_call.fixed
+++ b/tests/ui/expect_fun_call.fixed
@@ -106,7 +106,14 @@ fn main() {
         Some("foo").unwrap_or_else(|| panic!("{}", get_non_static_str(&0)));
         //~^ expect_fun_call
 
-        Some("foo").expect(const_evaluable());
+        Some("foo").unwrap_or_else(|| panic!("{}", const_evaluable()));
+        //~^ expect_fun_call
+
+        const {
+            Some("foo").expect(const_evaluable());
+        }
+
+        Some("foo").expect(const { const_evaluable() });
     }
 
     //Issue #3839
diff --git a/tests/ui/expect_fun_call.rs b/tests/ui/expect_fun_call.rs
index 160bbe64c65..bc58d24bc81 100644
--- a/tests/ui/expect_fun_call.rs
+++ b/tests/ui/expect_fun_call.rs
@@ -107,6 +107,13 @@ fn main() {
         //~^ expect_fun_call
 
         Some("foo").expect(const_evaluable());
+        //~^ expect_fun_call
+
+        const {
+            Some("foo").expect(const_evaluable());
+        }
+
+        Some("foo").expect(const { const_evaluable() });
     }
 
     //Issue #3839
diff --git a/tests/ui/expect_fun_call.stderr b/tests/ui/expect_fun_call.stderr
index 7988e8fc238..0692ecb4862 100644
--- a/tests/ui/expect_fun_call.stderr
+++ b/tests/ui/expect_fun_call.stderr
@@ -68,28 +68,34 @@ LL |         Some("foo").expect(get_non_static_str(&0));
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_non_static_str(&0)))`
 
 error: function call inside of `expect`
-  --> tests/ui/expect_fun_call.rs:113:16
+  --> tests/ui/expect_fun_call.rs:109:21
+   |
+LL |         Some("foo").expect(const_evaluable());
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", const_evaluable()))`
+
+error: function call inside of `expect`
+  --> tests/ui/expect_fun_call.rs:120:16
    |
 LL |     Some(true).expect(&format!("key {}, {}", 1, 2));
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
 
 error: function call inside of `expect`
-  --> tests/ui/expect_fun_call.rs:120:17
+  --> tests/ui/expect_fun_call.rs:127:17
    |
 LL |         opt_ref.expect(&format!("{:?}", opt_ref));
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
 
 error: function call inside of `expect`
-  --> tests/ui/expect_fun_call.rs:125:20
+  --> tests/ui/expect_fun_call.rs:132:20
    |
 LL |     format_capture.expect(&format!("{error_code}"));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
 
 error: function call inside of `expect`
-  --> tests/ui/expect_fun_call.rs:129:30
+  --> tests/ui/expect_fun_call.rs:136:30
    |
 LL |     format_capture_and_value.expect(&format!("{error_code}, {}", 1));
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
 
-error: aborting due to 15 previous errors
+error: aborting due to 16 previous errors