diff options
| author | bors <bors@rust-lang.org> | 2023-08-02 19:02:47 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-02 19:02:47 +0000 |
| commit | 7af5ea14fc9a68037ec695e992559ac93e5f98a5 (patch) | |
| tree | 6f0eb3f95fab6bcc3449e30189d65580ed4f10b3 | |
| parent | 78f5e0d3ec539675941e80fd7ce9468c39f0e4b6 (diff) | |
| parent | 71c54137eadc730d01fe15c17df8bf3ba5d3b04b (diff) | |
| download | rust-7af5ea14fc9a68037ec695e992559ac93e5f98a5.tar.gz rust-7af5ea14fc9a68037ec695e992559ac93e5f98a5.zip | |
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
| -rw-r--r-- | clippy_lints/src/methods/expect_used.rs | 44 | ||||
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 39 | ||||
| -rw-r--r-- | clippy_lints/src/methods/unwrap_expect_used.rs | 83 | ||||
| -rw-r--r-- | clippy_lints/src/methods/unwrap_used.rs | 53 | ||||
| -rw-r--r-- | clippy_utils/src/ty.rs | 5 | ||||
| -rw-r--r-- | tests/ui-toml/expect_used/expect_used.stderr | 4 | ||||
| -rw-r--r-- | tests/ui-toml/unwrap_used/unwrap_used.stderr | 39 | ||||
| -rw-r--r-- | tests/ui/expect.stderr | 6 | ||||
| -rw-r--r-- | tests/ui/get_unwrap.stderr | 39 | ||||
| -rw-r--r-- | tests/ui/unwrap.stderr | 9 | ||||
| -rw-r--r-- | tests/ui/unwrap_expect_used.rs | 11 | ||||
| -rw-r--r-- | tests/ui/unwrap_expect_used.stderr | 24 |
12 files changed, 207 insertions, 149 deletions
diff --git a/clippy_lints/src/methods/expect_used.rs b/clippy_lints/src/methods/expect_used.rs deleted file mode 100644 index 614610335a1..00000000000 --- a/clippy_lints/src/methods/expect_used.rs +++ /dev/null @@ -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"), - ); - } -} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 62d565bcc5c..17483656cec 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -17,7 +17,6 @@ mod collapsible_str_replace; mod drain_collect; mod err_expect; mod expect_fun_call; -mod expect_used; mod extend_with_drain; mod filetype_is_file; mod filter_map; @@ -105,7 +104,7 @@ mod unnecessary_lazy_eval; mod unnecessary_literal_unwrap; mod unnecessary_sort_by; mod unnecessary_to_owned; -mod unwrap_used; +mod unwrap_expect_used; mod useless_asref; mod utils; mod vec_resize_to_zero; @@ -3948,13 +3947,27 @@ impl Methods { match method_call(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), - _ => 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); }, ("expect_err", [_]) => { 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]) => { string_extend_chars::check(cx, expr, recv, arg); @@ -4180,11 +4193,25 @@ impl Methods { _ => {}, } 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", []) => { 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]) => { match method_call(recv) { diff --git a/clippy_lints/src/methods/unwrap_expect_used.rs b/clippy_lints/src/methods/unwrap_expect_used.rs new file mode 100644 index 00000000000..7bd16b473ce --- /dev/null +++ b/clippy_lints/src/methods/unwrap_expect_used.rs @@ -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" + )); + } + }, + ); +} diff --git a/clippy_lints/src/methods/unwrap_used.rs b/clippy_lints/src/methods/unwrap_used.rs deleted file mode 100644 index 5e4c3daee64..00000000000 --- a/clippy_lints/src/methods/unwrap_used.rs +++ /dev/null @@ -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, - ); - } -} diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index d0e15aa8bb3..98e163abc58 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -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. /// /// This function is for associated types which are "known" to exist, and as such, will only return diff --git a/tests/ui-toml/expect_used/expect_used.stderr b/tests/ui-toml/expect_used/expect_used.stderr index 9eef0e1bfaa..815d009350f 100644 --- a/tests/ui-toml/expect_used/expect_used.stderr +++ b/tests/ui-toml/expect_used/expect_used.stderr @@ -4,7 +4,7 @@ error: used `expect()` on an `Option` value 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` error: used `expect()` on a `Result` value @@ -13,7 +13,7 @@ error: used `expect()` on a `Result` value 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 diff --git a/tests/ui-toml/unwrap_used/unwrap_used.stderr b/tests/ui-toml/unwrap_used/unwrap_used.stderr index 4c9bdfa9dba..10219beaf97 100644 --- a/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -12,7 +12,8 @@ error: used `unwrap()` on an `Option` value 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` 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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $DIR/unwrap_used.rs:40:17 @@ -41,7 +43,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/unwrap_used.rs:41:17 @@ -55,7 +58,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/unwrap_used.rs:42:17 @@ -69,7 +73,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/unwrap_used.rs:43:17 @@ -83,7 +88,8 @@ error: used `unwrap()` on an `Option` value 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $DIR/unwrap_used.rs:75:13 diff --git a/tests/ui/expect.stderr b/tests/ui/expect.stderr index be340340d47..f787fa973a3 100644 --- a/tests/ui/expect.stderr +++ b/tests/ui/expect.stderr @@ -4,7 +4,7 @@ error: used `expect()` on an `Option` value 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` error: used `expect()` on a `Result` value @@ -13,7 +13,7 @@ error: used `expect()` on a `Result` value 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 --> $DIR/expect.rs:12:13 @@ -21,7 +21,7 @@ error: used `expect_err()` on a `Result` value 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 diff --git a/tests/ui/get_unwrap.stderr b/tests/ui/get_unwrap.stderr index c567ed319b5..19dc9071fe7 100644 --- a/tests/ui/get_unwrap.stderr +++ b/tests/ui/get_unwrap.stderr @@ -16,7 +16,8 @@ error: used `unwrap()` on an `Option` value 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` 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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $DIR/get_unwrap.rs:40:17 @@ -45,7 +47,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/get_unwrap.rs:41:17 @@ -59,7 +62,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/get_unwrap.rs:42:17 @@ -73,7 +77,8 @@ error: used `unwrap()` on an `Option` value 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 --> $DIR/get_unwrap.rs:43:17 @@ -87,7 +92,8 @@ error: used `unwrap()` on an `Option` value 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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 --> $DIR/get_unwrap.rs:78:24 diff --git a/tests/ui/unwrap.stderr b/tests/ui/unwrap.stderr index 3796d942ff9..41db819f6fb 100644 --- a/tests/ui/unwrap.stderr +++ b/tests/ui/unwrap.stderr @@ -4,7 +4,8 @@ error: used `unwrap()` on an `Option` value 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` error: used `unwrap()` on a `Result` value @@ -13,7 +14,8 @@ error: used `unwrap()` on a `Result` value 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 --> $DIR/unwrap.rs:12:13 @@ -21,7 +23,8 @@ error: used `unwrap_err()` on a `Result` value 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 diff --git a/tests/ui/unwrap_expect_used.rs b/tests/ui/unwrap_expect_used.rs index 7f57efc53c9..26f92ccdefa 100644 --- a/tests/ui/unwrap_expect_used.rs +++ b/tests/ui/unwrap_expect_used.rs @@ -1,5 +1,8 @@ #![warn(clippy::unwrap_used, clippy::expect_used)] #![allow(clippy::unnecessary_literal_unwrap)] +#![feature(never_type)] + +use std::convert::Infallible; trait OptionExt { type Item; @@ -28,6 +31,14 @@ fn main() { Some(3).unwrap_err(); 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); a.unwrap(); a.expect("Hello world!"); diff --git a/tests/ui/unwrap_expect_used.stderr b/tests/ui/unwrap_expect_used.stderr index 1a551ab5ab8..f66e47612ad 100644 --- a/tests/ui/unwrap_expect_used.stderr +++ b/tests/ui/unwrap_expect_used.stderr @@ -1,52 +1,52 @@ 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(); | ^^^^^^^^^^^^^^^^ | - = 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` 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!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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` error: used `unwrap()` on a `Result` value - --> $DIR/unwrap_expect_used.rs:32:5 + --> $DIR/unwrap_expect_used.rs:43:5 | 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 - --> $DIR/unwrap_expect_used.rs:33:5 + --> $DIR/unwrap_expect_used.rs:44:5 | 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 - --> $DIR/unwrap_expect_used.rs:34:5 + --> $DIR/unwrap_expect_used.rs:45:5 | 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 - --> $DIR/unwrap_expect_used.rs:35:5 + --> $DIR/unwrap_expect_used.rs:46:5 | 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 |
