]>
Commit | Line | Data |
---|---|---|
04454e1e FG |
1 | use super::ERR_EXPECT; |
2 | use clippy_utils::diagnostics::span_lint_and_sugg; | |
487cf647 | 3 | use clippy_utils::msrvs::{self, Msrv}; |
2b03887a | 4 | use clippy_utils::ty::has_debug_impl; |
487cf647 | 5 | use clippy_utils::ty::is_type_diagnostic_item; |
04454e1e FG |
6 | use rustc_errors::Applicability; |
7 | use rustc_lint::LateContext; | |
8 | use rustc_middle::ty; | |
9 | use rustc_middle::ty::Ty; | |
04454e1e FG |
10 | use rustc_span::{sym, Span}; |
11 | ||
12 | pub(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`). | |
48 | fn 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 | } |