fix: unwrap_used and expect_used FN when using fully qualified syntax

This commit is contained in:
linshuy2 2026-01-31 17:48:26 +00:00
parent dc8b277271
commit 631120b803
4 changed files with 139 additions and 1 deletions

View file

@ -4965,6 +4965,16 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
io_other_error::check(cx, expr, func, args, self.msrv);
swap_with_temporary::check(cx, expr, func, args);
ip_constant::check(cx, expr, func, args);
unwrap_expect_used::check_call(
cx,
expr,
func,
args,
self.allow_unwrap_in_tests,
self.allow_expect_in_tests,
self.allow_unwrap_in_consts,
self.allow_expect_in_consts,
);
},
ExprKind::MethodCall(..) => {
self.check_methods(cx, expr);

View file

@ -3,6 +3,7 @@ use clippy_utils::res::MaybeDef;
use clippy_utils::ty::is_never_like;
use clippy_utils::{is_in_test, is_inside_always_const_context, is_lint_allowed};
use rustc_hir::Expr;
use rustc_hir::def::DefKind;
use rustc_lint::{LateContext, Lint};
use rustc_middle::ty;
use rustc_span::sym;
@ -87,3 +88,70 @@ pub(super) fn check(
},
);
}
#[expect(clippy::too_many_arguments, clippy::fn_params_excessive_bools)]
pub(super) fn check_call(
cx: &LateContext<'_>,
expr: &Expr<'_>,
func: &Expr<'_>,
args: &[Expr<'_>],
allow_unwrap_in_consts: bool,
allow_unwrap_in_tests: bool,
allow_expect_in_consts: bool,
allow_expect_in_tests: bool,
) {
let Some(recv) = args.first() else {
return;
};
let Some((DefKind::AssocFn, def_id)) = cx.typeck_results().type_dependent_def(func.hir_id) else {
return;
};
match cx.tcx.item_name(def_id) {
sym::unwrap => {
check(
cx,
expr,
recv,
false,
allow_unwrap_in_consts,
allow_unwrap_in_tests,
Variant::Unwrap,
);
},
sym::expect => {
check(
cx,
expr,
recv,
false,
allow_expect_in_consts,
allow_expect_in_tests,
Variant::Expect,
);
},
clippy_utils::sym::unwrap_err => {
check(
cx,
expr,
recv,
true,
allow_unwrap_in_consts,
allow_unwrap_in_tests,
Variant::Unwrap,
);
},
clippy_utils::sym::expect_err => {
check(
cx,
expr,
recv,
true,
allow_expect_in_consts,
allow_expect_in_tests,
Variant::Expect,
);
},
_ => (),
}
}

View file

@ -83,3 +83,15 @@ mod with_expansion {
let _ = open!(file).expect_err("can open"); //~ expect_used
}
}
fn issue16484() {
let opt = Some(());
Option::unwrap(opt); //~ unwrap_used
Option::expect(opt, "error message"); //~ expect_used
let res: Result<(), i32> = Ok(());
Result::unwrap(res); //~ unwrap_used
Result::expect(res, "error message"); //~ expect_used
Result::unwrap_err(res); //~ unwrap_used
Result::expect_err(res, "error message"); //~ expect_used
}

View file

@ -82,5 +82,53 @@ LL | let _ = open!(file).expect_err("can open");
|
= note: if this value is an `Ok`, it will panic
error: aborting due to 10 previous errors
error: used `unwrap()` on an `Option` value
--> tests/ui/unwrap_expect_used.rs:89:5
|
LL | Option::unwrap(opt);
| ^^^^^^^^^^^^^^^^^^^
|
= note: if this value is `None`, it will panic
error: used `expect()` on an `Option` value
--> tests/ui/unwrap_expect_used.rs:90:5
|
LL | Option::expect(opt, "error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: if this value is `None`, it will panic
error: used `unwrap()` on a `Result` value
--> tests/ui/unwrap_expect_used.rs:93:5
|
LL | Result::unwrap(res);
| ^^^^^^^^^^^^^^^^^^^
|
= note: if this value is an `Err`, it will panic
error: used `expect()` on a `Result` value
--> tests/ui/unwrap_expect_used.rs:94:5
|
LL | Result::expect(res, "error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: if this value is an `Err`, it will panic
error: used `unwrap_err()` on a `Result` value
--> tests/ui/unwrap_expect_used.rs:95:5
|
LL | Result::unwrap_err(res);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: if this value is an `Ok`, it will panic
error: used `expect_err()` on a `Result` value
--> tests/ui/unwrap_expect_used.rs:96:5
|
LL | Result::expect_err(res, "error message");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: if this value is an `Ok`, it will panic
error: aborting due to 16 previous errors