Skip to content

Commit 2387f68

Browse files
RickyRicky
authored andcommitted
Removed map_err suggestion in lint, and updated lint documentation example
1 parent 3377291 commit 2387f68

File tree

2 files changed

+60
-62
lines changed

2 files changed

+60
-62
lines changed

clippy_lints/src/map_err_ignore.rs

Lines changed: 57 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use crate::utils::span_lint_and_sugg;
2-
use rustc_errors::Applicability;
3-
use rustc_hir::{CaptureBy, Expr, ExprKind, PatKind, QPath};
1+
use crate::utils::span_lint_and_help;
2+
3+
use rustc_hir::{CaptureBy, Expr, ExprKind, PatKind};
44
use rustc_lint::{LateContext, LateLintPass};
55
use rustc_session::{declare_lint_pass, declare_tool_lint};
66

@@ -12,33 +12,58 @@ declare_clippy_lint! {
1212
/// **Known problems:** None.
1313
///
1414
/// **Example:**
15-
///
15+
/// Before:
1616
/// ```rust
17+
/// use std::convert::TryFrom;
18+
///
19+
/// #[derive(Debug)]
1720
/// enum Errors {
18-
/// Ignore
19-
///}
20-
///fn main() -> Result<(), Errors> {
21+
/// Ignored
22+
/// }
2123
///
22-
/// let x = u32::try_from(-123_i32);
24+
/// fn divisible_by_3(inp: i32) -> Result<u32, Errors> {
25+
/// let i = u32::try_from(inp).map_err(|_| Errors::Ignored)?;
2326
///
24-
/// println!("{:?}", x.map_err(|_| Errors::Ignore));
27+
/// Ok(i)
28+
/// }
29+
/// ```
2530
///
26-
/// Ok(())
27-
///}
28-
/// ```
29-
/// Use instead:
30-
/// ```rust
31-
/// enum Errors {
32-
/// WithContext(TryFromIntError)
33-
///}
34-
///fn main() -> Result<(), Errors> {
31+
/// After:
32+
/// ```rust
33+
/// use std::convert::TryFrom;
34+
/// use std::num::TryFromIntError;
35+
/// use std::fmt;
36+
/// use std::error::Error;
37+
///
38+
/// #[derive(Debug)]
39+
/// enum ParseError {
40+
/// Indivisible {
41+
/// source: TryFromIntError,
42+
/// input: String,
43+
/// }
44+
/// }
45+
///
46+
/// impl fmt::Display for ParseError {
47+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
/// match &self {
49+
/// ParseError::Indivisible{source: _, input} => write!(f, "Error: {}", input)
50+
/// }
51+
/// }
52+
/// }
53+
///
54+
/// impl Error for ParseError {}
3555
///
36-
/// let x = u32::try_from(-123_i32);
56+
/// impl ParseError {
57+
/// fn new(source: TryFromIntError, input: String) -> ParseError {
58+
/// ParseError::Indivisible{source, input}
59+
/// }
60+
/// }
3761
///
38-
/// println!("{:?}", x.map_err(|e| Errors::WithContext(e)));
62+
/// fn divisible_by_3(inp: i32) -> Result<u32, ParseError> {
63+
/// let i = u32::try_from(inp).map_err(|e| ParseError::new(e, e.to_string()))?;
3964
///
40-
/// Ok(())
41-
///}
65+
/// Ok(i)
66+
/// }
4267
/// ```
4368
pub MAP_ERR_IGNORE,
4469
style,
@@ -69,44 +94,16 @@ impl<'tcx> LateLintPass<'tcx> for MapErrIgnore {
6994
if closure_body.params.len() == 1 {
7095
// make sure that parameter is the wild token (`_`)
7196
if let PatKind::Wild = closure_body.params[0].pat.kind {
72-
// Check the value of the closure to see if we can build the enum we are throwing away
73-
// the error for make sure this is a Path
74-
if let ExprKind::Path(q_path) = &closure_body.value.kind {
75-
// this should be a resolved path, only keep the path field
76-
if let QPath::Resolved(_, path) = q_path {
77-
// finally get the idents for each path segment collect them as a string and
78-
// join them with the path separator ("::"")
79-
let closure_fold: String = path
80-
.segments
81-
.iter()
82-
.map(|x| x.ident.as_str().to_string())
83-
.collect::<Vec<String>>()
84-
.join("::");
85-
//Span the body of the closure (the |...| bit) and suggest the fix by taking
86-
// the error and encapsulating it in the enum
87-
span_lint_and_sugg(
88-
cx,
89-
MAP_ERR_IGNORE,
90-
body_span,
91-
"`map_err` has thrown away the original error",
92-
"Allow the error enum to encapsulate the original error",
93-
format!("|e| {}(e)", closure_fold),
94-
Applicability::HasPlaceholders,
95-
);
96-
}
97-
} else {
98-
//If we cannot build the enum in a human readable way just suggest not throwing way
99-
// the error
100-
span_lint_and_sugg(
101-
cx,
102-
MAP_ERR_IGNORE,
103-
body_span,
104-
"`map_err` has thrown away the original error",
105-
"Allow the error enum to encapsulate the original error",
106-
"|e|".to_string(),
107-
Applicability::HasPlaceholders,
108-
);
109-
}
97+
// span the area of the closure capture and warn that the
98+
// original error will be thrown away
99+
span_lint_and_help(
100+
cx,
101+
MAP_ERR_IGNORE,
102+
body_span,
103+
"`map_else(|_|...` ignores the original error",
104+
None,
105+
"Consider wrapping the error in an enum variant",
106+
);
110107
}
111108
}
112109
}

tests/ui/map_err.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
error: `map_err` has thrown away the original error
1+
error: `map_else(|_|...` ignores the original error
22
--> $DIR/map_err.rs:21:32
33
|
44
LL | println!("{:?}", x.map_err(|_| Errors::Ignored));
5-
| ^^^ help: Allow the error enum to encapsulate the original error: `|e| Errors::Ignored(e)`
5+
| ^^^
66
|
77
= note: `-D clippy::map-err-ignore` implied by `-D warnings`
8+
= help: Consider wrapping the error in an enum variant
89

910
error: aborting due to previous error
1011

0 commit comments

Comments
 (0)