Skip to content

Commit e707447

Browse files
committed
Boilerplate for the new lint
1 parent 1af23d2 commit e707447

File tree

4 files changed

+92
-17
lines changed

4 files changed

+92
-17
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ mod unnecessary_fold;
9393
mod unnecessary_iter_cloned;
9494
mod unnecessary_join;
9595
mod unnecessary_lazy_eval;
96+
mod unnecessary_literal_unwrap;
9697
mod unnecessary_sort_by;
9798
mod unnecessary_to_owned;
9899
mod unwrap_or_else_default;
@@ -273,6 +274,56 @@ declare_clippy_lint! {
273274
"using `.unwrap()` on `Result` or `Option`, which should at least get a better message using `expect()`"
274275
}
275276

277+
declare_clippy_lint! {
278+
/// ### What it does
279+
/// Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.
280+
///
281+
/// ### Why is this bad?
282+
/// It is better to handle the `None` or `Err` case,
283+
/// or at least call `.expect(_)` with a more helpful message. Still, for a lot of
284+
/// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is
285+
/// `Allow` by default.
286+
///
287+
/// `result.unwrap()` will let the thread panic on `Err` values.
288+
/// Normally, you want to implement more sophisticated error handling,
289+
/// and propagate errors upwards with `?` operator.
290+
///
291+
/// Even if you want to panic on errors, not all `Error`s implement good
292+
/// messages on display. Therefore, it may be beneficial to look at the places
293+
/// where they may get displayed. Activate this lint to do just that.
294+
///
295+
/// ### Examples
296+
/// ```rust
297+
/// # let option = Some(1);
298+
/// # let result: Result<usize, ()> = Ok(1);
299+
/// option.unwrap();
300+
/// result.unwrap();
301+
/// ```
302+
///
303+
/// Use instead:
304+
/// ```rust
305+
/// # let option = Some(1);
306+
/// # let result: Result<usize, ()> = Ok(1);
307+
/// option.expect("more helpful message");
308+
/// result.expect("more helpful message");
309+
/// ```
310+
///
311+
/// If [expect_used](#expect_used) is enabled, instead:
312+
/// ```rust,ignore
313+
/// # let option = Some(1);
314+
/// # let result: Result<usize, ()> = Ok(1);
315+
/// option?;
316+
///
317+
/// // or
318+
///
319+
/// result?;
320+
/// ```
321+
#[clippy::version = "1.69.0"]
322+
pub UNNECESSARY_LITERAL_UNWRAP,
323+
complexity,
324+
"checks for calls of `unwrap()` or `expect()` on `Some()` that cannot fail"
325+
}
326+
276327
declare_clippy_lint! {
277328
/// ### What it does
278329
/// Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.
@@ -3814,6 +3865,7 @@ impl Methods {
38143865
Some(("or", recv, [or_arg], or_span, _)) => {
38153866
or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
38163867
},
3868+
// unnecessary_literal_unwrap::check(cx, expr, recv);
38173869
_ => {},
38183870
}
38193871
unwrap_used::check(cx, expr, recv, false, self.allow_unwrap_in_tests);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::ty::is_type_diagnostic_item;
3+
use rustc_hir as hir;
4+
use rustc_lint::LateContext;
5+
use rustc_span::sym;
6+
7+
use super::UNNECESSARY_LITERAL_UNWRAP;
8+
9+
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
10+
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
11+
12+
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
13+
Some((UNNECESSARY_LITERAL_UNWRAP, "an `Option`", "None", ""))
14+
} else {
15+
None
16+
};
17+
18+
if let Some((lint, kind, none_value, none_prefix)) = mess {
19+
let help = format!("if this value is {none_prefix}`{none_value}`, it will panic");
20+
21+
span_lint_and_help(
22+
cx,
23+
lint,
24+
expr.span,
25+
&format!("used `unwrap()` on {kind} value"),
26+
None,
27+
&help,
28+
);
29+
}
30+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![warn(clippy::unnecessary_literal_unwrap)]
2+
3+
fn unwrap_option() {
4+
let val = Some(1).unwrap();
5+
let val = Some(1).expect("this never happens");
6+
}
7+
8+
fn main() {
9+
unwrap_option();
10+
}

tests/ui/unwrap_literal.rs

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)