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