]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/methods/err_expect.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / methods / err_expect.rs
CommitLineData
04454e1e 1use super::ERR_EXPECT;
ed00b5ec 2use clippy_config::msrvs::{self, Msrv};
04454e1e 3use clippy_utils::diagnostics::span_lint_and_sugg;
add651ee 4use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item};
04454e1e
FG
5use rustc_errors::Applicability;
6use rustc_lint::LateContext;
7use rustc_middle::ty;
8use rustc_middle::ty::Ty;
04454e1e
FG
9use rustc_span::{sym, Span};
10
11pub(super) fn check(
12 cx: &LateContext<'_>,
13 _expr: &rustc_hir::Expr<'_>,
14 recv: &rustc_hir::Expr<'_>,
04454e1e
FG
15 expect_span: Span,
16 err_span: Span,
487cf647 17 msrv: &Msrv,
04454e1e
FG
18) {
19 if_chain! {
20 if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
21 // Test the version to make sure the lint can be showed (expect_err has been
22 // introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982)
487cf647 23 if msrv.meets(msrvs::EXPECT_ERR);
04454e1e
FG
24
25 // Grabs the `Result<T, E>` type
26 let result_type = cx.typeck_results().expr_ty(recv);
27 // Tests if the T type in a `Result<T, E>` is not None
28 if let Some(data_type) = get_data_type(cx, result_type);
29 // Tests if the T type in a `Result<T, E>` implements debug
2b03887a 30 if has_debug_impl(cx, data_type);
04454e1e
FG
31
32 then {
33 span_lint_and_sugg(
34 cx,
35 ERR_EXPECT,
36 err_span.to(expect_span),
37 "called `.err().expect()` on a `Result` value",
38 "try",
39 "expect_err".to_string(),
40 Applicability::MachineApplicable
41 );
42 }
43 };
44}
45
46/// Given a `Result<T, E>` type, return its data (`T`).
47fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
48 match ty.kind() {
add651ee 49 ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().next(),
04454e1e
FG
50 _ => None,
51 }
52}