From e1b713ab09f3ad7f84a81761a7c06609141ae686 Mon Sep 17 00:00:00 2001 From: linshuy2 Date: Mon, 23 Mar 2026 17:33:24 +0000 Subject: [PATCH] fix: `expect_fun_call` suggests wrongly for string slicing --- clippy_lints/src/methods/expect_fun_call.rs | 8 +++++++- tests/ui/expect_fun_call.fixed | 10 ++++++++++ tests/ui/expect_fun_call.rs | 10 ++++++++++ tests/ui/expect_fun_call.stderr | 14 +++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index 081f958bc8b7..89b37d507b70 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -75,7 +75,13 @@ fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Ex let mut arg_root = peel_blocks(arg); loop { arg_root = match &arg_root.kind { - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr, + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => { + let expr_ty = cx.typeck_results().expr_ty(expr); + if expr_ty.is_str() { + break; + } + expr + }, hir::ExprKind::MethodCall(method_name, receiver, [], ..) => { if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && { let arg_type = cx.typeck_results().expr_ty(receiver); diff --git a/tests/ui/expect_fun_call.fixed b/tests/ui/expect_fun_call.fixed index b923521afde1..cc407adc75ad 100644 --- a/tests/ui/expect_fun_call.fixed +++ b/tests/ui/expect_fun_call.fixed @@ -147,3 +147,13 @@ fn main() { return; }); } + +fn issue16747() { + let x = 42; + let _c = char::from_u32(x).unwrap_or_else(|| panic!("{}", &format!("Illegal: {x}")[..])); + //~^ expect_fun_call + + let s = "hello"; + let _c = char::from_u32(x).unwrap_or_else(|| panic!("{}", &s.to_lowercase()[..2])); + //~^ expect_fun_call +} diff --git a/tests/ui/expect_fun_call.rs b/tests/ui/expect_fun_call.rs index bc58d24bc812..ab3b43686552 100644 --- a/tests/ui/expect_fun_call.rs +++ b/tests/ui/expect_fun_call.rs @@ -147,3 +147,13 @@ const fn const_evaluable() -> &'static str { return; }); } + +fn issue16747() { + let x = 42; + let _c = char::from_u32(x).expect(&format!("Illegal: {x}")[..]); + //~^ expect_fun_call + + let s = "hello"; + let _c = char::from_u32(x).expect(&s.to_lowercase()[..2]); + //~^ expect_fun_call +} diff --git a/tests/ui/expect_fun_call.stderr b/tests/ui/expect_fun_call.stderr index 0692ecb4862e..4ef114ac406b 100644 --- a/tests/ui/expect_fun_call.stderr +++ b/tests/ui/expect_fun_call.stderr @@ -97,5 +97,17 @@ error: function call inside of `expect` LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))` -error: aborting due to 16 previous errors +error: function call inside of `expect` + --> tests/ui/expect_fun_call.rs:153:32 + | +LL | let _c = char::from_u32(x).expect(&format!("Illegal: {x}")[..]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", &format!("Illegal: {x}")[..]))` + +error: function call inside of `expect` + --> tests/ui/expect_fun_call.rs:157:32 + | +LL | let _c = char::from_u32(x).expect(&s.to_lowercase()[..2]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", &s.to_lowercase()[..2]))` + +error: aborting due to 18 previous errors