Optionally allow expect
and unwrap
in tests
This commit is contained in:
parent
bdfea1c095
commit
597f61bbe3
@ -582,8 +582,17 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
});
|
});
|
||||||
|
|
||||||
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
|
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
|
||||||
|
let allow_expect_in_tests = conf.allow_expect_in_tests;
|
||||||
|
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
|
||||||
store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
|
store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
|
||||||
store.register_late_pass(move || Box::new(methods::Methods::new(avoid_breaking_exported_api, msrv)));
|
store.register_late_pass(move || {
|
||||||
|
Box::new(methods::Methods::new(
|
||||||
|
avoid_breaking_exported_api,
|
||||||
|
msrv,
|
||||||
|
allow_expect_in_tests,
|
||||||
|
allow_unwrap_in_tests,
|
||||||
|
))
|
||||||
|
});
|
||||||
store.register_late_pass(move || Box::new(matches::Matches::new(msrv)));
|
store.register_late_pass(move || Box::new(matches::Matches::new(msrv)));
|
||||||
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
|
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
|
||||||
store.register_late_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
|
store.register_late_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
|
use clippy_utils::is_in_test_function;
|
||||||
use clippy_utils::ty::is_type_diagnostic_item;
|
use clippy_utils::ty::is_type_diagnostic_item;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
@ -7,7 +8,7 @@ use rustc_span::sym;
|
|||||||
use super::EXPECT_USED;
|
use super::EXPECT_USED;
|
||||||
|
|
||||||
/// lint use of `expect()` for `Option`s and `Result`s
|
/// lint use of `expect()` for `Option`s and `Result`s
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
|
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_expect_in_tests: bool) {
|
||||||
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||||
|
|
||||||
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
|
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
|
||||||
@ -18,6 +19,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if allow_expect_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((lint, kind, none_value)) = mess {
|
if let Some((lint, kind, none_value)) = mess {
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
|
@ -2200,14 +2200,23 @@ declare_clippy_lint! {
|
|||||||
pub struct Methods {
|
pub struct Methods {
|
||||||
avoid_breaking_exported_api: bool,
|
avoid_breaking_exported_api: bool,
|
||||||
msrv: Option<RustcVersion>,
|
msrv: Option<RustcVersion>,
|
||||||
|
allow_expect_in_tests: bool,
|
||||||
|
allow_unwrap_in_tests: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Methods {
|
impl Methods {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(avoid_breaking_exported_api: bool, msrv: Option<RustcVersion>) -> Self {
|
pub fn new(
|
||||||
|
avoid_breaking_exported_api: bool,
|
||||||
|
msrv: Option<RustcVersion>,
|
||||||
|
allow_expect_in_tests: bool,
|
||||||
|
allow_unwrap_in_tests: bool,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
avoid_breaking_exported_api,
|
avoid_breaking_exported_api,
|
||||||
msrv,
|
msrv,
|
||||||
|
allow_expect_in_tests,
|
||||||
|
allow_unwrap_in_tests,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2306,7 +2315,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_methods(cx, expr, self.msrv);
|
self.check_methods(cx, expr);
|
||||||
|
|
||||||
match expr.kind {
|
match expr.kind {
|
||||||
hir::ExprKind::Call(func, args) => {
|
hir::ExprKind::Call(func, args) => {
|
||||||
@ -2505,8 +2514,9 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||||||
extract_msrv_attr!(LateContext);
|
extract_msrv_attr!(LateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Methods {
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Option<RustcVersion>) {
|
fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if let Some((name, [recv, args @ ..], span)) = method_call(expr) {
|
if let Some((name, [recv, args @ ..], span)) = method_call(expr) {
|
||||||
match (name, args) {
|
match (name, args) {
|
||||||
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
|
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
|
||||||
@ -2525,7 +2535,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
|
("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
|
||||||
("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
|
("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
|
||||||
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
|
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
|
||||||
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, msrv),
|
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv),
|
||||||
("collect", []) => match method_call(recv) {
|
("collect", []) => match method_call(recv) {
|
||||||
Some((name @ ("cloned" | "copied"), [recv2], _)) => {
|
Some((name @ ("cloned" | "copied"), [recv2], _)) => {
|
||||||
iter_cloned_collect::check(cx, name, expr, recv2);
|
iter_cloned_collect::check(cx, name, expr, recv2);
|
||||||
@ -2534,7 +2544,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
|
map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
|
||||||
},
|
},
|
||||||
Some(("take", [take_self_arg, take_arg], _)) => {
|
Some(("take", [take_self_arg, take_arg], _)) => {
|
||||||
if meets_msrv(msrv, msrvs::STR_REPEAT) {
|
if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
|
||||||
manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
|
manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2553,8 +2563,8 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
},
|
},
|
||||||
("expect", [_]) => match method_call(recv) {
|
("expect", [_]) => 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, msrv, span, err_span),
|
Some(("err", [recv], err_span)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
|
||||||
_ => expect_used::check(cx, expr, recv),
|
_ => expect_used::check(cx, expr, recv, self.allow_expect_in_tests),
|
||||||
},
|
},
|
||||||
("extend", [arg]) => {
|
("extend", [arg]) => {
|
||||||
string_extend_chars::check(cx, expr, recv, arg);
|
string_extend_chars::check(cx, expr, recv, arg);
|
||||||
@ -2584,7 +2594,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
},
|
},
|
||||||
("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
|
("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
|
||||||
("is_file", []) => filetype_is_file::check(cx, expr, recv),
|
("is_file", []) => filetype_is_file::check(cx, expr, recv),
|
||||||
("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, msrv),
|
("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
|
||||||
("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
|
("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
|
||||||
("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
|
("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
|
||||||
("join", [join_arg]) => {
|
("join", [join_arg]) => {
|
||||||
@ -2602,12 +2612,14 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
(name @ ("map" | "map_err"), [m_arg]) => {
|
(name @ ("map" | "map_err"), [m_arg]) => {
|
||||||
if let Some((name, [recv2, args @ ..], span2)) = method_call(recv) {
|
if let Some((name, [recv2, args @ ..], span2)) = method_call(recv) {
|
||||||
match (name, args) {
|
match (name, args) {
|
||||||
("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, msrv),
|
("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),
|
||||||
("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, msrv),
|
("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),
|
||||||
("filter", [f_arg]) => {
|
("filter", [f_arg]) => {
|
||||||
filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
|
filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
|
||||||
},
|
},
|
||||||
("find", [f_arg]) => filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true),
|
("find", [f_arg]) => {
|
||||||
|
filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true);
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2619,7 +2631,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
match (name2, args2) {
|
match (name2, args2) {
|
||||||
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
|
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
|
||||||
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
|
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
|
||||||
("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, msrv),
|
("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv),
|
||||||
("iter", []) => iter_next_slice::check(cx, expr, recv2),
|
("iter", []) => iter_next_slice::check(cx, expr, recv2),
|
||||||
("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg),
|
("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg),
|
||||||
("skip_while", [_]) => skip_while_next::check(cx, expr),
|
("skip_while", [_]) => skip_while_next::check(cx, expr),
|
||||||
@ -2643,7 +2655,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
("splitn" | "rsplitn", [count_arg, pat_arg]) => {
|
("splitn" | "rsplitn", [count_arg, pat_arg]) => {
|
||||||
if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
|
if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
|
||||||
suspicious_splitn::check(cx, name, expr, recv, count);
|
suspicious_splitn::check(cx, name, expr, recv, count);
|
||||||
str_splitn::check(cx, name, expr, recv, pat_arg, count, msrv);
|
str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
|
("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
|
||||||
@ -2676,7 +2688,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
unwrap_used::check(cx, expr, recv);
|
unwrap_used::check(cx, expr, recv, self.allow_unwrap_in_tests);
|
||||||
},
|
},
|
||||||
("unwrap_or", [u_arg]) => match method_call(recv) {
|
("unwrap_or", [u_arg]) => match method_call(recv) {
|
||||||
Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), [lhs, rhs], _)) => {
|
Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), [lhs, rhs], _)) => {
|
||||||
@ -2688,7 +2700,8 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
_ => {},
|
_ => {},
|
||||||
},
|
},
|
||||||
("unwrap_or_else", [u_arg]) => match method_call(recv) {
|
("unwrap_or_else", [u_arg]) => match method_call(recv) {
|
||||||
Some(("map", [recv, map_arg], _)) if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, msrv) => {},
|
Some(("map", [recv, map_arg], _))
|
||||||
|
if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},
|
||||||
_ => {
|
_ => {
|
||||||
unwrap_or_else_default::check(cx, expr, recv, u_arg);
|
unwrap_or_else_default::check(cx, expr, recv, u_arg);
|
||||||
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
|
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
|
||||||
@ -2698,6 +2711,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, is_some: bool) {
|
fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, is_some: bool) {
|
||||||
if let Some((name @ ("find" | "position" | "rposition"), [f_recv, arg], span)) = method_call(recv) {
|
if let Some((name @ ("find" | "position" | "rposition"), [f_recv, arg], span)) = method_call(recv) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
|
use clippy_utils::is_in_test_function;
|
||||||
use clippy_utils::ty::is_type_diagnostic_item;
|
use clippy_utils::ty::is_type_diagnostic_item;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
@ -7,7 +8,7 @@ use rustc_span::sym;
|
|||||||
use super::UNWRAP_USED;
|
use super::UNWRAP_USED;
|
||||||
|
|
||||||
/// lint use of `unwrap()` for `Option`s and `Result`s
|
/// lint use of `unwrap()` for `Option`s and `Result`s
|
||||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
|
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_unwrap_in_tests: bool) {
|
||||||
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||||
|
|
||||||
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
|
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
|
||||||
@ -18,6 +19,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if allow_unwrap_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((lint, kind, none_value)) = mess {
|
if let Some((lint, kind, none_value)) = mess {
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
|
@ -316,6 +316,14 @@ define_Conf! {
|
|||||||
///
|
///
|
||||||
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||||
(max_include_file_size: u64 = 1_000_000),
|
(max_include_file_size: u64 = 1_000_000),
|
||||||
|
/// Lint: EXPECT_USED.
|
||||||
|
///
|
||||||
|
/// Whether `expect` should be allowed in test functions
|
||||||
|
(allow_expect_in_tests: bool = false),
|
||||||
|
/// Lint: UNWRAP_USED.
|
||||||
|
///
|
||||||
|
/// Whether `unwrap` should be allowed in test functions
|
||||||
|
(allow_unwrap_in_tests: bool = false),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search for the configuration file.
|
/// Search for the configuration file.
|
||||||
|
1
tests/ui-toml/expect_used/clippy.toml
Normal file
1
tests/ui-toml/expect_used/clippy.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
allow-expect-in-tests = true
|
29
tests/ui-toml/expect_used/expect_used.rs
Normal file
29
tests/ui-toml/expect_used/expect_used.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// compile-flags: --test
|
||||||
|
#![warn(clippy::expect_used)]
|
||||||
|
|
||||||
|
fn expect_option() {
|
||||||
|
let opt = Some(0);
|
||||||
|
let _ = opt.expect("");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_result() {
|
||||||
|
let res: Result<u8, ()> = Ok(0);
|
||||||
|
let _ = res.expect("");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
expect_option();
|
||||||
|
expect_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_expect_option() {
|
||||||
|
let opt = Some(0);
|
||||||
|
let _ = opt.expect("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_expect_result() {
|
||||||
|
let res: Result<u8, ()> = Ok(0);
|
||||||
|
let _ = res.expect("");
|
||||||
|
}
|
19
tests/ui-toml/expect_used/expect_used.stderr
Normal file
19
tests/ui-toml/expect_used/expect_used.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error: used `expect()` on `an Option` value
|
||||||
|
--> $DIR/expect_used.rs:6:13
|
||||||
|
|
|
||||||
|
LL | let _ = opt.expect("");
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::expect-used` implied by `-D warnings`
|
||||||
|
= help: if this value is an `None`, it will panic
|
||||||
|
|
||||||
|
error: used `expect()` on `a Result` value
|
||||||
|
--> $DIR/expect_used.rs:11:13
|
||||||
|
|
|
||||||
|
LL | let _ = res.expect("");
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: if this value is an `Err`, it will panic
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `third-party` at line 5 column 1
|
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `allow-expect-in-tests`, `allow-unwrap-in-tests`, `third-party` at line 5 column 1
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
1
tests/ui-toml/unwrap_used/clippy.toml
Normal file
1
tests/ui-toml/unwrap_used/clippy.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
allow-unwrap-in-tests = true
|
74
tests/ui-toml/unwrap_used/unwrap_used.rs
Normal file
74
tests/ui-toml/unwrap_used/unwrap_used.rs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// compile-flags: --test
|
||||||
|
|
||||||
|
#![allow(unused_mut, clippy::from_iter_instead_of_collect)]
|
||||||
|
#![warn(clippy::unwrap_used)]
|
||||||
|
#![deny(clippy::get_unwrap)]
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
struct GetFalsePositive {
|
||||||
|
arr: [u32; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetFalsePositive {
|
||||||
|
fn get(&self, pos: usize) -> Option<&u32> {
|
||||||
|
self.arr.get(pos)
|
||||||
|
}
|
||||||
|
fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {
|
||||||
|
self.arr.get_mut(pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
|
||||||
|
let mut some_slice = &mut [0, 1, 2, 3];
|
||||||
|
let mut some_vec = vec![0, 1, 2, 3];
|
||||||
|
let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();
|
||||||
|
let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);
|
||||||
|
let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);
|
||||||
|
let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test `get().unwrap()`
|
||||||
|
let _ = boxed_slice.get(1).unwrap();
|
||||||
|
let _ = some_slice.get(0).unwrap();
|
||||||
|
let _ = some_vec.get(0).unwrap();
|
||||||
|
let _ = some_vecdeque.get(0).unwrap();
|
||||||
|
let _ = some_hashmap.get(&1).unwrap();
|
||||||
|
let _ = some_btreemap.get(&1).unwrap();
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
let _ = false_positive.get(0).unwrap();
|
||||||
|
// Test with deref
|
||||||
|
let _: u8 = *boxed_slice.get(1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test `get_mut().unwrap()`
|
||||||
|
*boxed_slice.get_mut(0).unwrap() = 1;
|
||||||
|
*some_slice.get_mut(0).unwrap() = 1;
|
||||||
|
*some_vec.get_mut(0).unwrap() = 1;
|
||||||
|
*some_vecdeque.get_mut(0).unwrap() = 1;
|
||||||
|
// Check false positives
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
{
|
||||||
|
*some_hashmap.get_mut(&1).unwrap() = 'b';
|
||||||
|
*some_btreemap.get_mut(&1).unwrap() = 'b';
|
||||||
|
*false_positive.get_mut(0).unwrap() = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`
|
||||||
|
let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||||
|
let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
|
||||||
|
let _ = boxed_slice.get(1).unwrap();
|
||||||
|
}
|
197
tests/ui-toml/unwrap_used/unwrap_used.stderr
Normal file
197
tests/ui-toml/unwrap_used/unwrap_used.stderr
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:36:17
|
||||||
|
|
|
||||||
|
LL | let _ = boxed_slice.get(1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]`
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/unwrap_used.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![deny(clippy::get_unwrap)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:36:17
|
||||||
|
|
|
||||||
|
LL | let _ = boxed_slice.get(1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::unwrap-used` implied by `-D warnings`
|
||||||
|
= help: if you don't want to handle the `None` case gracefully, 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:37:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_slice.get(0).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:37:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:38:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_vec.get(0).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:38:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:39:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_vecdeque.get(0).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:39:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:40:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_hashmap.get(&1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:40:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:41:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_btreemap.get(&1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:41:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:45:21
|
||||||
|
|
|
||||||
|
LL | let _: u8 = *boxed_slice.get(1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:45:22
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:50:9
|
||||||
|
|
|
||||||
|
LL | *boxed_slice.get_mut(0).unwrap() = 1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:50:10
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:51:9
|
||||||
|
|
|
||||||
|
LL | *some_slice.get_mut(0).unwrap() = 1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:51:10
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:52:9
|
||||||
|
|
|
||||||
|
LL | *some_vec.get_mut(0).unwrap() = 1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:52:10
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:53:9
|
||||||
|
|
|
||||||
|
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:53:10
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:65:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:65:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:66:17
|
||||||
|
|
|
||||||
|
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
|
||||||
|
|
||||||
|
error: used `unwrap()` on `an Option` value
|
||||||
|
--> $DIR/unwrap_used.rs:66:17
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
||||||
|
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
|
||||||
|
--> $DIR/unwrap_used.rs:73:13
|
||||||
|
|
|
||||||
|
LL | let _ = boxed_slice.get(1).unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]`
|
||||||
|
|
||||||
|
error: aborting due to 27 previous errors
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user