2 use clippy_utils::diagnostics::span_lint_and_sugg;
3 use clippy_utils::ty::has_debug_impl;
4 use clippy_utils::{meets_msrv, msrvs, ty::is_type_diagnostic_item};
5 use rustc_errors::Applicability;
6 use rustc_lint::LateContext;
8 use rustc_middle::ty::Ty;
9 use rustc_semver::RustcVersion;
10 use rustc_span::{sym, Span};
14 _expr: &rustc_hir::Expr<'_>,
15 recv: &rustc_hir::Expr<'_>,
16 msrv: Option<RustcVersion>,
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)
24 if meets_msrv(msrv, msrvs::EXPECT_ERR);
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
31 if has_debug_impl(cx, data_type);
37 err_span.to(expect_span),
38 "called `.err().expect()` on a `Result` value",
40 "expect_err".to_string(),
41 Applicability::MachineApplicable
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>> {
50 ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().next(),