Skip to content

Commit fcd064d

Browse files
committed
expect_fun_call: only lint const fn's if they're not inside a const context
1 parent 07e2d96 commit fcd064d

File tree

4 files changed

+43
-9
lines changed

4 files changed

+43
-9
lines changed

clippy_lints/src/methods/expect_fun_call.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::eager_or_lazy::switch_to_lazy_eval;
32
use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};
43
use clippy_utils::source::snippet_with_applicability;
54
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
6-
use clippy_utils::{contains_return, peel_blocks};
5+
use clippy_utils::visitors::for_each_expr;
6+
use clippy_utils::{contains_return, is_inside_always_const_context, peel_blocks};
77
use rustc_errors::Applicability;
88
use rustc_hir as hir;
99
use rustc_lint::LateContext;
1010
use rustc_span::symbol::sym;
1111
use rustc_span::{Span, Symbol};
1212
use std::borrow::Cow;
13+
use std::ops::ControlFlow;
1314

1415
use super::EXPECT_FUN_CALL;
1516

@@ -48,10 +49,23 @@ pub(super) fn check<'tcx>(
4849
arg_root
4950
}
5051

52+
fn contains_call<'a>(cx: &LateContext<'a>, arg: &'a hir::Expr<'a>) -> bool {
53+
for_each_expr(cx, arg, |expr| {
54+
if matches!(expr.kind, hir::ExprKind::MethodCall { .. } | hir::ExprKind::Call { .. })
55+
&& !is_inside_always_const_context(cx.tcx, expr.hir_id)
56+
{
57+
ControlFlow::Break(())
58+
} else {
59+
ControlFlow::Continue(())
60+
}
61+
})
62+
.is_some()
63+
}
64+
5165
if name == sym::expect
5266
&& let [arg] = args
5367
&& let arg_root = get_arg_root(cx, arg)
54-
&& switch_to_lazy_eval(cx, arg_root)
68+
&& contains_call(cx, arg_root)
5569
&& !contains_return(arg_root)
5670
{
5771
let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);

tests/ui/expect_fun_call.fixed

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,14 @@ fn main() {
106106
Some("foo").unwrap_or_else(|| panic!("{}", get_non_static_str(&0)));
107107
//~^ expect_fun_call
108108

109-
Some("foo").expect(const_evaluable());
109+
Some("foo").unwrap_or_else(|| panic!("{}", const_evaluable()));
110+
//~^ expect_fun_call
111+
112+
const {
113+
Some("foo").expect(const_evaluable());
114+
}
115+
116+
Some("foo").expect(const { const_evaluable() });
110117
}
111118

112119
//Issue #3839

tests/ui/expect_fun_call.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ fn main() {
107107
//~^ expect_fun_call
108108

109109
Some("foo").expect(const_evaluable());
110+
//~^ expect_fun_call
111+
112+
const {
113+
Some("foo").expect(const_evaluable());
114+
}
115+
116+
Some("foo").expect(const { const_evaluable() });
110117
}
111118

112119
//Issue #3839

tests/ui/expect_fun_call.stderr

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,34 @@ LL | Some("foo").expect(get_non_static_str(&0));
6868
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_non_static_str(&0)))`
6969

7070
error: function call inside of `expect`
71-
--> tests/ui/expect_fun_call.rs:113:16
71+
--> tests/ui/expect_fun_call.rs:109:21
72+
|
73+
LL | Some("foo").expect(const_evaluable());
74+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", const_evaluable()))`
75+
76+
error: function call inside of `expect`
77+
--> tests/ui/expect_fun_call.rs:120:16
7278
|
7379
LL | Some(true).expect(&format!("key {}, {}", 1, 2));
7480
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
7581

7682
error: function call inside of `expect`
77-
--> tests/ui/expect_fun_call.rs:120:17
83+
--> tests/ui/expect_fun_call.rs:127:17
7884
|
7985
LL | opt_ref.expect(&format!("{:?}", opt_ref));
8086
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
8187

8288
error: function call inside of `expect`
83-
--> tests/ui/expect_fun_call.rs:125:20
89+
--> tests/ui/expect_fun_call.rs:132:20
8490
|
8591
LL | format_capture.expect(&format!("{error_code}"));
8692
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
8793

8894
error: function call inside of `expect`
89-
--> tests/ui/expect_fun_call.rs:129:30
95+
--> tests/ui/expect_fun_call.rs:136:30
9096
|
9197
LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1));
9298
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
9399

94-
error: aborting due to 15 previous errors
100+
error: aborting due to 16 previous errors
95101

0 commit comments

Comments
 (0)