Auto merge of #11252 - Centri3:#11245, r=xFrednet

[`unwrap_used`]: Do not lint unwrapping on `!` or never-like enums

Fixes #11245

changelog: [`unwrap_used`]: Do not lint unwrapping on `!` or never-like enums
changelog: [`expect_used`]: Do not lint unwrapping on `!` or never-like enums
This commit is contained in:
bors 2023-08-02 19:02:47 +00:00
commit 7af5ea14fc
12 changed files with 207 additions and 149 deletions

View file

@ -1,44 +0,0 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{is_in_cfg_test, is_in_test_function};
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
use super::EXPECT_USED;
/// lint use of `expect()` or `expect_err` for `Result` and `expect()` for `Option`.
pub(super) fn check(
cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
recv: &hir::Expr<'_>,
is_err: bool,
allow_expect_in_tests: bool,
) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
Some((EXPECT_USED, "an `Option`", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
Some((EXPECT_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
let method = if is_err { "expect_err" } else { "expect" };
if allow_expect_in_tests && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id)) {
return;
}
if let Some((lint, kind, none_value, none_prefix)) = mess {
span_lint_and_help(
cx,
lint,
expr.span,
&format!("used `{method}()` on {kind} value"),
None,
&format!("if this value is {none_prefix}`{none_value}`, it will panic"),
);
}
}

View file

@ -17,7 +17,6 @@ mod collapsible_str_replace;
mod drain_collect; mod drain_collect;
mod err_expect; mod err_expect;
mod expect_fun_call; mod expect_fun_call;
mod expect_used;
mod extend_with_drain; mod extend_with_drain;
mod filetype_is_file; mod filetype_is_file;
mod filter_map; mod filter_map;
@ -105,7 +104,7 @@ mod unnecessary_lazy_eval;
mod unnecessary_literal_unwrap; mod unnecessary_literal_unwrap;
mod unnecessary_sort_by; mod unnecessary_sort_by;
mod unnecessary_to_owned; mod unnecessary_to_owned;
mod unwrap_used; mod unwrap_expect_used;
mod useless_asref; mod useless_asref;
mod utils; mod utils;
mod vec_resize_to_zero; mod vec_resize_to_zero;
@ -3948,13 +3947,27 @@ impl Methods {
match method_call(recv) { match method_call(recv) {
Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv),
Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv), Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv),
_ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests), _ => unwrap_expect_used::check(
cx,
expr,
recv,
false,
self.allow_expect_in_tests,
unwrap_expect_used::Variant::Expect,
),
} }
unnecessary_literal_unwrap::check(cx, expr, recv, name, args); unnecessary_literal_unwrap::check(cx, expr, recv, name, args);
}, },
("expect_err", [_]) => { ("expect_err", [_]) => {
unnecessary_literal_unwrap::check(cx, expr, recv, name, args); unnecessary_literal_unwrap::check(cx, expr, recv, name, args);
expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests); unwrap_expect_used::check(
cx,
expr,
recv,
true,
self.allow_expect_in_tests,
unwrap_expect_used::Variant::Expect,
);
}, },
("extend", [arg]) => { ("extend", [arg]) => {
string_extend_chars::check(cx, expr, recv, arg); string_extend_chars::check(cx, expr, recv, arg);
@ -4180,11 +4193,25 @@ impl Methods {
_ => {}, _ => {},
} }
unnecessary_literal_unwrap::check(cx, expr, recv, name, args); unnecessary_literal_unwrap::check(cx, expr, recv, name, args);
unwrap_used::check(cx, expr, recv, false, self.allow_unwrap_in_tests); unwrap_expect_used::check(
cx,
expr,
recv,
false,
self.allow_unwrap_in_tests,
unwrap_expect_used::Variant::Unwrap,
);
}, },
("unwrap_err", []) => { ("unwrap_err", []) => {
unnecessary_literal_unwrap::check(cx, expr, recv, name, args); unnecessary_literal_unwrap::check(cx, expr, recv, name, args);
unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests); unwrap_expect_used::check(
cx,
expr,
recv,
true,
self.allow_unwrap_in_tests,
unwrap_expect_used::Variant::Unwrap,
);
}, },
("unwrap_or", [u_arg]) => { ("unwrap_or", [u_arg]) => {
match method_call(recv) { match method_call(recv) {

View file

@ -0,0 +1,83 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::{is_never_like, is_type_diagnostic_item};
use clippy_utils::{is_in_cfg_test, is_in_test_function, is_lint_allowed};
use rustc_hir::Expr;
use rustc_lint::{LateContext, Lint};
use rustc_middle::ty;
use rustc_span::sym;
use super::{EXPECT_USED, UNWRAP_USED};
#[derive(Clone, Copy, Eq, PartialEq)]
pub(super) enum Variant {
Unwrap,
Expect,
}
impl Variant {
fn method_name(self, is_err: bool) -> &'static str {
match (self, is_err) {
(Variant::Unwrap, true) => "unwrap_err",
(Variant::Unwrap, false) => "unwrap",
(Variant::Expect, true) => "expect_err",
(Variant::Expect, false) => "expect",
}
}
fn lint(self) -> &'static Lint {
match self {
Variant::Unwrap => UNWRAP_USED,
Variant::Expect => EXPECT_USED,
}
}
}
/// Lint usage of `unwrap` or `unwrap_err` for `Result` and `unwrap()` for `Option` (and their
/// `expect` counterparts).
pub(super) fn check(
cx: &LateContext<'_>,
expr: &Expr<'_>,
recv: &Expr<'_>,
is_err: bool,
allow_unwrap_in_tests: bool,
variant: Variant,
) {
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
let (kind, none_value, none_prefix) = if is_type_diagnostic_item(cx, ty, sym::Option) && !is_err {
("an `Option`", "None", "")
} else if is_type_diagnostic_item(cx, ty, sym::Result)
&& let ty::Adt(_, substs) = ty.kind()
&& let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type()
{
if is_never_like(t_or_e_ty) {
return;
}
("a `Result`", if is_err { "Ok" } else { "Err" }, "an ")
} else {
return;
};
let method_suffix = if is_err { "_err" } else { "" };
if allow_unwrap_in_tests && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id)) {
return;
}
span_lint_and_then(
cx,
variant.lint(),
expr.span,
&format!("used `{}()` on {kind} value", variant.method_name(is_err)),
|diag| {
diag.note(format!("if this value is {none_prefix}`{none_value}`, it will panic"));
if variant == Variant::Unwrap && is_lint_allowed(cx, EXPECT_USED, expr.hir_id) {
diag.help(format!(
"consider using `expect{method_suffix}()` to provide a better panic message"
));
}
},
);
}

View file

@ -1,53 +0,0 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{is_in_cfg_test, is_in_test_function, is_lint_allowed};
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
use super::{EXPECT_USED, UNWRAP_USED};
/// lint use of `unwrap()` or `unwrap_err` for `Result` and `unwrap()` for `Option`.
pub(super) fn check(
cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
recv: &hir::Expr<'_>,
is_err: bool,
allow_unwrap_in_tests: bool,
) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
Some((UNWRAP_USED, "an `Option`", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
Some((UNWRAP_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
let method_suffix = if is_err { "_err" } else { "" };
if allow_unwrap_in_tests && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id)) {
return;
}
if let Some((lint, kind, none_value, none_prefix)) = mess {
let help = if is_lint_allowed(cx, EXPECT_USED, expr.hir_id) {
format!(
"if you don't want to handle the `{none_value}` case gracefully, consider \
using `expect{method_suffix}()` to provide a better panic message"
)
} else {
format!("if this value is {none_prefix}`{none_value}`, it will panic")
};
span_lint_and_help(
cx,
lint,
expr.span,
&format!("used `unwrap{method_suffix}()` on {kind} value"),
None,
&help,
);
}
}

View file

@ -1093,6 +1093,11 @@ fn assert_generic_args_match<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, args: &[Generi
} }
} }
/// Returns whether `ty` is never-like; i.e., `!` (never) or an enum with zero variants.
pub fn is_never_like(ty: Ty<'_>) -> bool {
ty.is_never() || (ty.is_enum() && ty.ty_adt_def().is_some_and(|def| def.variants().is_empty()))
}
/// Makes the projection type for the named associated type in the given impl or trait impl. /// Makes the projection type for the named associated type in the given impl or trait impl.
/// ///
/// This function is for associated types which are "known" to exist, and as such, will only return /// This function is for associated types which are "known" to exist, and as such, will only return

View file

@ -4,7 +4,7 @@ error: used `expect()` on an `Option` value
LL | let _ = opt.expect(""); LL | let _ = opt.expect("");
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= help: if this value is `None`, it will panic = note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings` = note: `-D clippy::expect-used` implied by `-D warnings`
error: used `expect()` on a `Result` value error: used `expect()` on a `Result` value
@ -13,7 +13,7 @@ error: used `expect()` on a `Result` value
LL | let _ = res.expect(""); LL | let _ = res.expect("");
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= help: if this value is an `Err`, it will panic = note: if this value is an `Err`, it will panic
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -12,7 +12,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = boxed_slice.get(1).unwrap(); LL | let _ = boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings` = note: `-D clippy::unwrap-used` implied by `-D warnings`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
@ -27,7 +28,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_slice.get(0).unwrap(); LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:40:17 --> $DIR/unwrap_used.rs:40:17
@ -41,7 +43,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get(0).unwrap(); LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:41:17 --> $DIR/unwrap_used.rs:41:17
@ -55,7 +58,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vecdeque.get(0).unwrap(); LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:42:17 --> $DIR/unwrap_used.rs:42:17
@ -69,7 +73,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_hashmap.get(&1).unwrap(); LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:43:17 --> $DIR/unwrap_used.rs:43:17
@ -83,7 +88,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_btreemap.get(&1).unwrap(); LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:47:21 --> $DIR/unwrap_used.rs:47:21
@ -97,7 +103,8 @@ error: used `unwrap()` on an `Option` value
LL | let _: u8 = *boxed_slice.get(1).unwrap(); LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:52:9 --> $DIR/unwrap_used.rs:52:9
@ -111,7 +118,8 @@ error: used `unwrap()` on an `Option` value
LL | *boxed_slice.get_mut(0).unwrap() = 1; LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:53:9 --> $DIR/unwrap_used.rs:53:9
@ -125,7 +133,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_slice.get_mut(0).unwrap() = 1; LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:54:9 --> $DIR/unwrap_used.rs:54:9
@ -139,7 +148,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_vec.get_mut(0).unwrap() = 1; LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:55:9 --> $DIR/unwrap_used.rs:55:9
@ -153,7 +163,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_vecdeque.get_mut(0).unwrap() = 1; LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:67:17 --> $DIR/unwrap_used.rs:67:17
@ -167,7 +178,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get(0..1).unwrap().to_vec(); LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:68:17 --> $DIR/unwrap_used.rs:68:17
@ -181,7 +193,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/unwrap_used.rs:75:13 --> $DIR/unwrap_used.rs:75:13

View file

@ -4,7 +4,7 @@ error: used `expect()` on an `Option` value
LL | let _ = opt.expect(""); LL | let _ = opt.expect("");
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= help: if this value is `None`, it will panic = note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings` = note: `-D clippy::expect-used` implied by `-D warnings`
error: used `expect()` on a `Result` value error: used `expect()` on a `Result` value
@ -13,7 +13,7 @@ error: used `expect()` on a `Result` value
LL | let _ = res.expect(""); LL | let _ = res.expect("");
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= help: if this value is an `Err`, it will panic = note: if this value is an `Err`, it will panic
error: used `expect_err()` on a `Result` value error: used `expect_err()` on a `Result` value
--> $DIR/expect.rs:12:13 --> $DIR/expect.rs:12:13
@ -21,7 +21,7 @@ error: used `expect_err()` on a `Result` value
LL | let _ = res.expect_err(""); LL | let _ = res.expect_err("");
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= help: if this value is an `Ok`, it will panic = note: if this value is an `Ok`, it will panic
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -16,7 +16,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = boxed_slice.get(1).unwrap(); LL | let _ = boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings` = note: `-D clippy::unwrap-used` implied by `-D warnings`
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
@ -31,7 +32,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_slice.get(0).unwrap(); LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:40:17 --> $DIR/get_unwrap.rs:40:17
@ -45,7 +47,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get(0).unwrap(); LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:41:17 --> $DIR/get_unwrap.rs:41:17
@ -59,7 +62,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vecdeque.get(0).unwrap(); LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:42:17 --> $DIR/get_unwrap.rs:42:17
@ -73,7 +77,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_hashmap.get(&1).unwrap(); LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:43:17 --> $DIR/get_unwrap.rs:43:17
@ -87,7 +92,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_btreemap.get(&1).unwrap(); LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:47:21 --> $DIR/get_unwrap.rs:47:21
@ -101,7 +107,8 @@ error: used `unwrap()` on an `Option` value
LL | let _: u8 = *boxed_slice.get(1).unwrap(); LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:52:9 --> $DIR/get_unwrap.rs:52:9
@ -115,7 +122,8 @@ error: used `unwrap()` on an `Option` value
LL | *boxed_slice.get_mut(0).unwrap() = 1; LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:53:9 --> $DIR/get_unwrap.rs:53:9
@ -129,7 +137,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_slice.get_mut(0).unwrap() = 1; LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:54:9 --> $DIR/get_unwrap.rs:54:9
@ -143,7 +152,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_vec.get_mut(0).unwrap() = 1; LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:55:9 --> $DIR/get_unwrap.rs:55:9
@ -157,7 +167,8 @@ error: used `unwrap()` on an `Option` value
LL | *some_vecdeque.get_mut(0).unwrap() = 1; LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:67:17 --> $DIR/get_unwrap.rs:67:17
@ -171,7 +182,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get(0..1).unwrap().to_vec(); LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:68:17 --> $DIR/get_unwrap.rs:68:17
@ -185,7 +197,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec(); LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
--> $DIR/get_unwrap.rs:78:24 --> $DIR/get_unwrap.rs:78:24

View file

@ -4,7 +4,8 @@ error: used `unwrap()` on an `Option` value
LL | let _ = opt.unwrap(); LL | let _ = opt.unwrap();
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is `None`, it will panic
= help: consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings` = note: `-D clippy::unwrap-used` implied by `-D warnings`
error: used `unwrap()` on a `Result` value error: used `unwrap()` on a `Result` value
@ -13,7 +14,8 @@ error: used `unwrap()` on a `Result` value
LL | let _ = res.unwrap(); LL | let _ = res.unwrap();
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: if you don't want to handle the `Err` case gracefully, consider using `expect()` to provide a better panic message = note: if this value is an `Err`, it will panic
= help: consider using `expect()` to provide a better panic message
error: used `unwrap_err()` on a `Result` value error: used `unwrap_err()` on a `Result` value
--> $DIR/unwrap.rs:12:13 --> $DIR/unwrap.rs:12:13
@ -21,7 +23,8 @@ error: used `unwrap_err()` on a `Result` value
LL | let _ = res.unwrap_err(); LL | let _ = res.unwrap_err();
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: if you don't want to handle the `Ok` case gracefully, consider using `expect_err()` to provide a better panic message = note: if this value is an `Ok`, it will panic
= help: consider using `expect_err()` to provide a better panic message
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -1,5 +1,8 @@
#![warn(clippy::unwrap_used, clippy::expect_used)] #![warn(clippy::unwrap_used, clippy::expect_used)]
#![allow(clippy::unnecessary_literal_unwrap)] #![allow(clippy::unnecessary_literal_unwrap)]
#![feature(never_type)]
use std::convert::Infallible;
trait OptionExt { trait OptionExt {
type Item; type Item;
@ -28,6 +31,14 @@ fn main() {
Some(3).unwrap_err(); Some(3).unwrap_err();
Some(3).expect_err("Hellow none!"); Some(3).expect_err("Hellow none!");
// Issue #11245: The `Err` variant can never be constructed so do not lint this.
let x: Result<(), !> = Ok(());
x.unwrap();
x.expect("is `!` (never)");
let x: Result<(), Infallible> = Ok(());
x.unwrap();
x.expect("is never-like (0 variants)");
let a: Result<i32, i32> = Ok(3); let a: Result<i32, i32> = Ok(3);
a.unwrap(); a.unwrap();
a.expect("Hello world!"); a.expect("Hello world!");

View file

@ -1,52 +1,52 @@
error: used `unwrap()` on an `Option` value error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_expect_used.rs:24:5 --> $DIR/unwrap_expect_used.rs:27:5
| |
LL | Some(3).unwrap(); LL | Some(3).unwrap();
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: if this value is `None`, it will panic = note: if this value is `None`, it will panic
= note: `-D clippy::unwrap-used` implied by `-D warnings` = note: `-D clippy::unwrap-used` implied by `-D warnings`
error: used `expect()` on an `Option` value error: used `expect()` on an `Option` value
--> $DIR/unwrap_expect_used.rs:25:5 --> $DIR/unwrap_expect_used.rs:28:5
| |
LL | Some(3).expect("Hello world!"); LL | Some(3).expect("Hello world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if this value is `None`, it will panic = note: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings` = note: `-D clippy::expect-used` implied by `-D warnings`
error: used `unwrap()` on a `Result` value error: used `unwrap()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:32:5 --> $DIR/unwrap_expect_used.rs:43:5
| |
LL | a.unwrap(); LL | a.unwrap();
| ^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: if this value is an `Err`, it will panic = note: if this value is an `Err`, it will panic
error: used `expect()` on a `Result` value error: used `expect()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:33:5 --> $DIR/unwrap_expect_used.rs:44:5
| |
LL | a.expect("Hello world!"); LL | a.expect("Hello world!");
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if this value is an `Err`, it will panic = note: if this value is an `Err`, it will panic
error: used `unwrap_err()` on a `Result` value error: used `unwrap_err()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:34:5 --> $DIR/unwrap_expect_used.rs:45:5
| |
LL | a.unwrap_err(); LL | a.unwrap_err();
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= help: if this value is an `Ok`, it will panic = note: if this value is an `Ok`, it will panic
error: used `expect_err()` on a `Result` value error: used `expect_err()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:35:5 --> $DIR/unwrap_expect_used.rs:46:5
| |
LL | a.expect_err("Hello error!"); LL | a.expect_err("Hello error!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: if this value is an `Ok`, it will panic = note: if this value is an `Ok`, it will panic
error: aborting due to 6 previous errors error: aborting due to 6 previous errors