-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #8606 - InfRandomness:err()-expect()-lint, r=xFrednet
Add [`err_expect`] lint [`expect_err`] lint - \[ ] Followed [lint naming conventions][lint_naming] - \[x] Added passing UI tests (including committed `.stderr` file) - \[x] `cargo test` passes locally - \[x] Executed `cargo dev update_lints` - \[x] Added lint documentation - \[x] Run `cargo dev fmt` Fixes #1435 changelog: Added a lint to detect usage of .err().expect()
- Loading branch information
Showing
9 changed files
with
138 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use super::ERR_EXPECT; | ||
use clippy_utils::diagnostics::span_lint_and_sugg; | ||
use clippy_utils::ty::implements_trait; | ||
use clippy_utils::{meets_msrv, msrvs, ty::is_type_diagnostic_item}; | ||
use rustc_errors::Applicability; | ||
use rustc_lint::LateContext; | ||
use rustc_middle::ty; | ||
use rustc_middle::ty::Ty; | ||
use rustc_semver::RustcVersion; | ||
use rustc_span::{sym, Span}; | ||
|
||
pub(super) fn check( | ||
cx: &LateContext<'_>, | ||
_expr: &rustc_hir::Expr<'_>, | ||
recv: &rustc_hir::Expr<'_>, | ||
msrv: Option<&RustcVersion>, | ||
expect_span: Span, | ||
err_span: Span, | ||
) { | ||
if_chain! { | ||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result); | ||
// Test the version to make sure the lint can be showed (expect_err has been | ||
// introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982) | ||
if meets_msrv(msrv, &msrvs::EXPECT_ERR); | ||
|
||
// Grabs the `Result<T, E>` type | ||
let result_type = cx.typeck_results().expr_ty(recv); | ||
// Tests if the T type in a `Result<T, E>` is not None | ||
if let Some(data_type) = get_data_type(cx, result_type); | ||
// Tests if the T type in a `Result<T, E>` implements debug | ||
if has_debug_impl(data_type, cx); | ||
|
||
then { | ||
span_lint_and_sugg( | ||
cx, | ||
ERR_EXPECT, | ||
err_span.to(expect_span), | ||
"called `.err().expect()` on a `Result` value", | ||
"try", | ||
"expect_err".to_string(), | ||
Applicability::MachineApplicable | ||
); | ||
} | ||
}; | ||
} | ||
|
||
/// Given a `Result<T, E>` type, return its data (`T`). | ||
fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> { | ||
match ty.kind() { | ||
ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().next(), | ||
_ => None, | ||
} | ||
} | ||
|
||
/// Given a type, very if the Debug trait has been impl'd | ||
fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool { | ||
cx.tcx | ||
.get_diagnostic_item(sym::Debug) | ||
.map_or(false, |debug| implements_trait(cx, ty, debug, &[])) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// run-rustfix | ||
|
||
struct MyTypeNonDebug; | ||
|
||
#[derive(Debug)] | ||
struct MyTypeDebug; | ||
|
||
fn main() { | ||
let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug); | ||
test_debug.expect_err("Testing debug type"); | ||
|
||
let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug); | ||
test_non_debug.err().expect("Testing non debug type"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// run-rustfix | ||
|
||
struct MyTypeNonDebug; | ||
|
||
#[derive(Debug)] | ||
struct MyTypeDebug; | ||
|
||
fn main() { | ||
let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug); | ||
test_debug.err().expect("Testing debug type"); | ||
|
||
let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug); | ||
test_non_debug.err().expect("Testing non debug type"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
error: called `.err().expect()` on a `Result` value | ||
--> $DIR/err_expect.rs:10:16 | ||
| | ||
LL | test_debug.err().expect("Testing debug type"); | ||
| ^^^^^^^^^^^^ help: try: `expect_err` | ||
| | ||
= note: `-D clippy::err-expect` implied by `-D warnings` | ||
|
||
error: aborting due to previous error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters