From 538513926ea3ceafc26dd5bbc80f1088862cbe93 Mon Sep 17 00:00:00 2001 From: Catherine <114838443+Centri3@users.noreply.github.com> Date: Tue, 27 Jun 2023 08:39:40 -0500 Subject: [PATCH] Extend `iter_on` to catch more cases --- clippy_lints/src/dereference.rs | 3 +- clippy_lints/src/manual_strip.rs | 8 +- .../iter_on_single_or_empty_collections.rs | 92 -------- clippy_lints/src/methods/mod.rs | 11 +- .../single_or_empty_collections_iter.rs | 209 ++++++++++++++++++ clippy_lints/src/ptr.rs | 8 +- clippy_lints/src/types/mod.rs | 2 + clippy_utils/src/consts.rs | 4 +- clippy_utils/src/lib.rs | 2 + clippy_utils/src/msrvs.rs | 1 + clippy_utils/src/ty.rs | 4 +- lintcheck/lintcheck_crates.toml | 2 + tests/ui/cloned_instead_of_copied.fixed | 2 +- tests/ui/cloned_instead_of_copied.rs | 2 +- tests/ui/eta.fixed | 1 + tests/ui/eta.rs | 1 + tests/ui/eta.stderr | 52 ++--- tests/ui/flat_map_option.fixed | 6 +- tests/ui/flat_map_option.rs | 6 +- tests/ui/flat_map_option.stderr | 4 +- tests/ui/issue_2356.fixed | 2 +- tests/ui/issue_2356.rs | 2 +- tests/ui/iter_not_returning_iterator.rs | 1 + tests/ui/iter_not_returning_iterator.stderr | 6 +- tests/ui/iter_on_empty_collections.fixed | 32 ++- tests/ui/iter_on_empty_collections.rs | 20 +- tests/ui/iter_on_empty_collections.stderr | 140 ++++++++++-- tests/ui/iter_on_single_items.fixed | 32 ++- tests/ui/iter_on_single_items.rs | 20 +- tests/ui/iter_on_single_items.stderr | 140 ++++++++++-- tests/ui/manual_map_option.fixed | 1 + tests/ui/manual_map_option.rs | 1 + tests/ui/manual_map_option.stderr | 42 ++-- tests/ui/map_clone.fixed | 1 + tests/ui/map_clone.rs | 1 + tests/ui/map_clone.stderr | 12 +- tests/ui/needless_collect_indirect.rs | 2 +- tests/ui/option_filter_map.fixed | 2 +- tests/ui/option_filter_map.rs | 2 +- tests/ui/search_is_some_fixable_none.fixed | 7 +- tests/ui/search_is_some_fixable_none.rs | 7 +- tests/ui/search_is_some_fixable_none.stderr | 86 +++---- tests/ui/search_is_some_fixable_some.fixed | 8 +- tests/ui/search_is_some_fixable_some.rs | 8 +- tests/ui/search_is_some_fixable_some.stderr | 94 ++++---- tests/ui/single_element_loop.fixed | 2 +- tests/ui/single_element_loop.rs | 2 +- tests/ui/try_err.fixed | 6 +- tests/ui/try_err.rs | 6 +- tests/ui/try_err.stderr | 22 +- 50 files changed, 785 insertions(+), 342 deletions(-) delete mode 100644 clippy_lints/src/methods/iter_on_single_or_empty_collections.rs create mode 100644 clippy_lints/src/methods/single_or_empty_collections_iter.rs diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 7787fc348daa..4123e7bb2524 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -34,6 +34,7 @@ use rustc_span::{symbol::sym, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; use std::collections::VecDeque; +use std::iter::once; declare_clippy_lint! { /// ### What it does @@ -893,7 +894,7 @@ fn walk_parents<'tcx>( && infcx .type_implements_trait( trait_id, - [impl_ty.into()].into_iter().chain(subs.iter().copied()), + once(impl_ty.into()).chain(subs.iter().copied()), cx.param_env, ) .must_apply_modulo_regions() diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs index 93d977a5c96b..cc1f1ff4ee4e 100644 --- a/clippy_lints/src/manual_strip.rs +++ b/clippy_lints/src/manual_strip.rs @@ -1,3 +1,5 @@ +use std::iter::once; + use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; use clippy_utils::msrvs::{self, Msrv}; @@ -113,11 +115,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip { multispan_sugg( diag, &format!("try using the `strip_{kind_word}` method"), - vec![(test_span, + once((test_span, format!("if let Some() = {}.strip_{kind_word}({}) ", snippet(cx, target_arg.span, ".."), - snippet(cx, pattern.span, "..")))] - .into_iter().chain(strippings.into_iter().map(|span| (span, "".into()))), + snippet(cx, pattern.span, "..")))) + .chain(strippings.into_iter().map(|span| (span, "".into()))), ); }); } diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs deleted file mode 100644 index 70abe4891d98..000000000000 --- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs +++ /dev/null @@ -1,92 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet; -use clippy_utils::{get_expr_use_or_unification_node, is_no_std_crate, is_res_lang_ctor, path_res}; - -use rustc_errors::Applicability; -use rustc_hir::LangItem::{OptionNone, OptionSome}; -use rustc_hir::{Expr, ExprKind, Node}; -use rustc_lint::LateContext; - -use super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS}; - -enum IterType { - Iter, - IterMut, - IntoIter, -} - -impl IterType { - fn ref_prefix(&self) -> &'static str { - match self { - Self::Iter => "&", - Self::IterMut => "&mut ", - Self::IntoIter => "", - } - } -} - -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) { - let item = match recv.kind { - ExprKind::Array([]) => None, - ExprKind::Array([e]) => Some(e), - ExprKind::Path(ref p) if is_res_lang_ctor(cx, cx.qpath_res(p, recv.hir_id), OptionNone) => None, - ExprKind::Call(f, [arg]) if is_res_lang_ctor(cx, path_res(cx, f), OptionSome) => Some(arg), - _ => return, - }; - let iter_type = match method_name { - "iter" => IterType::Iter, - "iter_mut" => IterType::IterMut, - "into_iter" => IterType::IntoIter, - _ => return, - }; - - let is_unified = match get_expr_use_or_unification_node(cx.tcx, expr) { - Some((Node::Expr(parent), child_id)) => match parent.kind { - ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id == child_id => false, - ExprKind::If(_, _, _) - | ExprKind::Match(_, _, _) - | ExprKind::Closure(_) - | ExprKind::Ret(_) - | ExprKind::Break(_, _) => true, - _ => false, - }, - Some((Node::Stmt(_) | Node::Local(_), _)) => false, - _ => true, - }; - - if is_unified { - return; - } - - if let Some(i) = item { - let sugg = format!( - "{}::iter::once({}{})", - if is_no_std_crate(cx) { "core" } else { "std" }, - iter_type.ref_prefix(), - snippet(cx, i.span, "...") - ); - span_lint_and_sugg( - cx, - ITER_ON_SINGLE_ITEMS, - expr.span, - &format!("`{method_name}` call on a collection with only one item"), - "try", - sugg, - Applicability::MaybeIncorrect, - ); - } else { - span_lint_and_sugg( - cx, - ITER_ON_EMPTY_COLLECTIONS, - expr.span, - &format!("`{method_name}` call on an empty collection"), - "try", - if is_no_std_crate(cx) { - "core::iter::empty()".to_string() - } else { - "std::iter::empty()".to_string() - }, - Applicability::MaybeIncorrect, - ); - } -} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 99c984ba65a8..3286873abf62 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -41,7 +41,6 @@ mod iter_kv_map; mod iter_next_slice; mod iter_nth; mod iter_nth_zero; -mod iter_on_single_or_empty_collections; mod iter_overeager_cloned; mod iter_skip_next; mod iter_with_drain; @@ -79,6 +78,7 @@ mod single_char_add_str; mod single_char_insert_string; mod single_char_pattern; mod single_char_push_string; +mod single_or_empty_collections_iter; mod skip_while_next; mod stable_sort_primitive; mod str_splitn; @@ -2437,7 +2437,7 @@ declare_clippy_lint! { /// The type of the resulting iterator might become incompatible with its usage #[clippy::version = "1.65.0"] pub ITER_ON_SINGLE_ITEMS, - nursery, + pedantic, "Iterator for array of length 1" } @@ -2469,7 +2469,7 @@ declare_clippy_lint! { /// The type of the resulting iterator might become incompatible with its usage #[clippy::version = "1.65.0"] pub ITER_ON_EMPTY_COLLECTIONS, - nursery, + pedantic, "Iterator for empty array" } @@ -3432,6 +3432,8 @@ fn method_call<'tcx>( impl<'tcx> LateLintPass<'tcx> for Methods { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { + single_or_empty_collections_iter::check(cx, expr, &self.msrv); + if expr.span.from_expansion() { return; } @@ -3725,9 +3727,6 @@ impl Methods { ("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_some", []) => check_is_some_is_none(cx, expr, recv, true), - ("iter" | "iter_mut" | "into_iter", []) => { - iter_on_single_or_empty_collections::check(cx, expr, name, recv); - }, ("join", [join_arg]) => { if let Some(("collect", _, _, span, _)) = method_call(recv) { unnecessary_join::check(cx, expr, recv, join_arg, span); diff --git a/clippy_lints/src/methods/single_or_empty_collections_iter.rs b/clippy_lints/src/methods/single_or_empty_collections_iter.rs new file mode 100644 index 000000000000..1bcf2f5baeba --- /dev/null +++ b/clippy_lints/src/methods/single_or_empty_collections_iter.rs @@ -0,0 +1,209 @@ +use clippy_utils::{ + diagnostics::span_lint_and_then, + get_parent_expr, + higher::VecArgs, + is_diagnostic_item_or_ctor, is_lang_item_or_ctor, last_path_segment, + macros::root_macro_call_first_node, + msrvs::{Msrv, ITER_ONCE_AND_EMPTY}, + path_res, + source::snippet_opt, + std_or_core, +}; +use rustc_errors::{Applicability, Diagnostic}; +use rustc_hir::{Expr, ExprKind, GenericArg, LangItem}; +use rustc_lint::{LateContext, Lint, LintContext}; +use rustc_middle::{ + lint::in_external_macro, + ty::{Clause, PredicateKind}, +}; +use rustc_span::{sym, Span}; + +use super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS}; + +#[derive(Clone, Copy, Debug)] +enum Variant<'tcx> { + SomeToOnce, + NoneToEmpty, + OneLenToOnce(&'tcx Expr<'tcx>), + ZeroLenToEmpty, +} + +impl<'tcx> Variant<'tcx> { + fn as_lint(self) -> &'static Lint { + match self { + Self::SomeToOnce | Self::OneLenToOnce(_) => ITER_ON_SINGLE_ITEMS, + Self::NoneToEmpty | Self::ZeroLenToEmpty => ITER_ON_EMPTY_COLLECTIONS, + } + } + + fn as_str(self) -> &'static str { + match self { + Self::SomeToOnce => "Some", + Self::NoneToEmpty => "None", + Self::OneLenToOnce(_) => "[T; 1]", + Self::ZeroLenToEmpty => "[T; 0]", + } + } + + fn desc(self) -> &'static str { + match self { + Self::SomeToOnce | Self::OneLenToOnce(_) => "iterator with only one element", + Self::NoneToEmpty | Self::ZeroLenToEmpty => "empty iterator", + } + } + + fn sugg_fn(self, cx: &LateContext<'_>) -> Option { + Some(format!( + "{}::iter::{}", + std_or_core(cx)?, + match self { + Self::SomeToOnce | Self::OneLenToOnce(_) => "once", + Self::NoneToEmpty | Self::ZeroLenToEmpty => "empty", + }, + )) + } + + fn turbofish_or_args_snippet( + self, + cx: &LateContext<'_>, + expr: &Expr<'_>, + method_name: Option<&str>, + ) -> Option { + let ref_prefix = ref_prefix(method_name.unwrap_or("")); + + match self { + Self::SomeToOnce if let ExprKind::Call(_, [arg]) = expr.kind => { + snippet_opt(cx, arg.span).map(|s| format!("({ref_prefix}{s})")) + }, + Self::NoneToEmpty if let ExprKind::Path(qpath) = expr.kind + && let Some(args) = last_path_segment(&qpath).args + && let [GenericArg::Type(ty)] = args.args => + { + snippet_opt(cx, ty.span).map(|s| format!("::<{s}>()")) + }, + Self::OneLenToOnce(one) => { + snippet_opt(cx, one.span).map(|s| format!("({ref_prefix}{s})")) + } + Self::NoneToEmpty | Self::ZeroLenToEmpty => Some("()".to_owned()), + Self::SomeToOnce => None, + } + } +} + +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, msrv: &Msrv) { + if !msrv.meets(ITER_ONCE_AND_EMPTY) { + return; + } + + let (variant, is_vec, sugg_span) = match expr.kind { + // `[T; 1]` + ExprKind::Array([one]) => (Variant::OneLenToOnce(one), false, expr.span), + // `[T; 0]` + ExprKind::Array([]) => (Variant::ZeroLenToEmpty, false, expr.span), + // `Some` + ExprKind::Call(path, _) if let Some(def_id) = path_res(cx, path).opt_def_id() + && is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome) => + { + (Variant::SomeToOnce, false, expr.span) + }, + // `None` + ExprKind::Path(qpath) if let Some(def_id) = cx.qpath_res(&qpath, expr.hir_id).opt_def_id() + && is_lang_item_or_ctor(cx, def_id, LangItem::OptionNone) => + { + (Variant::NoneToEmpty, false, expr.span) + } + // `vec![]` + _ if let Some(mac_call) = root_macro_call_first_node(cx, expr) + && let Some(VecArgs::Vec(elems)) = VecArgs::hir(cx, expr) => + { + if let [one] = elems { + (Variant::OneLenToOnce(one), true, mac_call.span.source_callsite()) + } else if elems.is_empty() { + (Variant::ZeroLenToEmpty, true, mac_call.span.source_callsite()) + } else { + return; + } + }, + _ => return, + }; + + // `vec![]` must be external + if !is_vec && in_external_macro(cx.sess(), expr.span) { + return; + } + + // FIXME: `get_expr_use_or_unification_node` doesn't work here. Even with the exact same check + // that the old code used. Please help + + if let Some(parent) = get_parent_expr(cx, expr) + && let ExprKind::MethodCall(path, recv, args, _) = parent + .peel_blocks() + .peel_borrows() + .kind + { + if recv.hir_id == expr.hir_id + && let method_name = path.ident.as_str() + && matches!(method_name, "iter" | "iter_mut" | "into_iter") + { + emit_lint(cx, expr, Some(path.ident.as_str()), parent.span, variant, |_| {}); + } else if args.iter().any(|arg| arg.hir_id == expr.hir_id) + && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) + { + for predicate in cx.tcx.param_env(def_id).caller_bounds() { + match predicate.kind().skip_binder() { + // FIXME: This doesn't take into account whether this `Clause` is related + // to `arg`, afaik + PredicateKind::Clause(Clause::Trait(trait_predicate)) + if is_diagnostic_item_or_ctor(cx, trait_predicate.def_id(), sym::Iterator) => + { + emit_lint(cx, expr, None, sugg_span, variant, |diag| { + diag.note("this method is generic over `Iterator`"); + }); + }, + _ => {}, + } + } + } + } + {} +} + +fn emit_lint<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + method_name: Option<&str>, + sugg_span: Span, + variant: Variant<'_>, + f: impl FnOnce(&mut Diagnostic), +) { + let Some(sugg_fn) = variant.sugg_fn(cx) else { + return; + }; + let Some(turbofish_or_args) = variant.turbofish_or_args_snippet(cx, expr, method_name) else { + return; + }; + + span_lint_and_then( + cx, + variant.as_lint(), + expr.span.source_callsite(), + &format!("usage of `{}` to create an {}", variant.as_str(), variant.desc()), + |diag| { + diag.span_suggestion( + sugg_span, + format!("use `{sugg_fn}` instead"), + format!("{sugg_fn}{turbofish_or_args}"), + Applicability::MachineApplicable, + ); + f(diag); + }, + ); +} + +fn ref_prefix(method_name: &str) -> &str { + match method_name { + "iter" => "&", + "iter_mut" => "&mut ", + _ => "", + } +} diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index e88543941509..58b5a863b083 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -29,7 +29,7 @@ use rustc_span::symbol::Symbol; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use std::fmt; -use std::iter; +use std::iter::{self, once}; declare_clippy_lint! { /// ### What it does @@ -725,7 +725,11 @@ fn matches_preds<'tcx>( let infcx = cx.tcx.infer_ctxt().build(); preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) { ExistentialPredicate::Trait(p) => infcx - .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env) + .type_implements_trait( + p.def_id, + once(ty.into()).chain(p.substs.iter()), + cx.param_env, + ) .must_apply_modulo_regions(), ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( cx.tcx, diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs index 3c873a5901d4..8c0a4cf27027 100644 --- a/clippy_lints/src/types/mod.rs +++ b/clippy_lints/src/types/mod.rs @@ -509,6 +509,7 @@ impl Types { QPath::Resolved(Some(ty), p) => { context.is_nested_call = true; self.check_ty(cx, ty, context); + #[expect(clippy::iter_on_empty_collections)] for ty in p.segments.iter().flat_map(|seg| { seg.args .as_ref() @@ -523,6 +524,7 @@ impl Types { }, QPath::Resolved(None, p) => { context.is_nested_call = true; + #[expect(clippy::iter_on_empty_collections)] for ty in p.segments.iter().flat_map(|seg| { seg.args .as_ref() diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 03dc9ca56ff2..7c732553d44f 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -18,7 +18,7 @@ use rustc_span::symbol::{Ident, Symbol}; use rustc_span::SyntaxContext; use std::cmp::Ordering::{self, Equal}; use std::hash::{Hash, Hasher}; -use std::iter; +use std::iter::{self, once}; /// A `LitKind`-like enum to fold constant `Expr`s into. #[derive(Debug, Clone)] @@ -536,7 +536,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { if !tokenize(src) .map(|t| t.kind) .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)) - .eq([OpenBrace]) + .eq(once(OpenBrace)) { self.source = ConstantSource::Constant; } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 078dcef19273..2415f1a231b9 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -526,6 +526,8 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator UintSimplifiedType(UintTy::U128), "f32" => FloatSimplifiedType(FloatTy::F32), "f64" => FloatSimplifiedType(FloatTy::F64), + // FIXME: False positive, see comment in `single_or_empty_collections_iter.rs` for more info + #[expect(clippy::iter_on_empty_collections)] _ => return [].iter().copied(), }; diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 0a4c3418a08e..6b46ef7c92b5 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -48,6 +48,7 @@ msrv_aliases! { 1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR } 1,16,0 { STR_REPEAT } 1,15,0 { MAYBE_BOUND_IN_WHERE } + 1,2,0 { ITER_ONCE_AND_EMPTY } } fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option) -> Option { diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 4132a6c4b18d..6c9ac80d60c5 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -26,7 +26,7 @@ use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Size, VariantIdx}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; -use std::iter; +use std::iter::{self, once}; use crate::{match_def_path, path_res, paths}; @@ -243,7 +243,7 @@ pub fn implements_trait_with_env<'tcx>( .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())), ); infcx - .type_implements_trait(trait_id, [ty.into()].into_iter().chain(ty_params), param_env) + .type_implements_trait(trait_id, once(ty.into()).chain(ty_params), param_env) .must_apply_modulo_regions() } diff --git a/lintcheck/lintcheck_crates.toml b/lintcheck/lintcheck_crates.toml index 52f7fee47b61..e43b211e223e 100644 --- a/lintcheck/lintcheck_crates.toml +++ b/lintcheck/lintcheck_crates.toml @@ -33,6 +33,8 @@ cfg-expr = {name = "cfg-expr", versions = ['0.7.1']} puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"} rpmalloc = {name = "rpmalloc", versions = ['0.2.0']} tame-oidc = {name = "tame-oidc", versions = ['0.1.0']} +bevy = {name = "bevy", versions = ['0.10.1']} +deno = {name = "deno", versions = ['1.34.3']} [recursive] ignore = [ diff --git a/tests/ui/cloned_instead_of_copied.fixed b/tests/ui/cloned_instead_of_copied.fixed index 34bd2233440b..70a0766158a7 100644 --- a/tests/ui/cloned_instead_of_copied.fixed +++ b/tests/ui/cloned_instead_of_copied.fixed @@ -2,7 +2,7 @@ #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] -#![allow(clippy::useless_vec)] +#![allow(clippy::iter_on_single_items, clippy::useless_vec)] fn main() { // yay diff --git a/tests/ui/cloned_instead_of_copied.rs b/tests/ui/cloned_instead_of_copied.rs index fa8444937b6b..ca1a86fe8358 100644 --- a/tests/ui/cloned_instead_of_copied.rs +++ b/tests/ui/cloned_instead_of_copied.rs @@ -2,7 +2,7 @@ #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] -#![allow(clippy::useless_vec)] +#![allow(clippy::iter_on_single_items, clippy::useless_vec)] fn main() { // yay diff --git a/tests/ui/eta.fixed b/tests/ui/eta.fixed index bf44bcb564ec..418b6c1efce1 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -2,6 +2,7 @@ #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( + clippy::iter_on_single_items, clippy::needless_borrow, clippy::needless_pass_by_value, clippy::no_effect, diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index b2af4bf09537..0f0df5c68513 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -2,6 +2,7 @@ #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( + clippy::iter_on_single_items, clippy::needless_borrow, clippy::needless_pass_by_value, clippy::no_effect, diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index 0ac0b901df44..de0238861864 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -1,5 +1,5 @@ error: redundant closure - --> $DIR/eta.rs:29:27 + --> $DIR/eta.rs:30:27 | LL | let a = Some(1u8).map(|a| foo(a)); | ^^^^^^^^^^ help: replace the closure with the function itself: `foo` @@ -7,31 +7,31 @@ LL | let a = Some(1u8).map(|a| foo(a)); = note: `-D clippy::redundant-closure` implied by `-D warnings` error: redundant closure - --> $DIR/eta.rs:33:40 + --> $DIR/eta.rs:34:40 | LL | let _: Option> = true.then(|| vec![]); // special case vec! | ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new` error: redundant closure - --> $DIR/eta.rs:34:35 + --> $DIR/eta.rs:35:35 | LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? | ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2` error: redundant closure - --> $DIR/eta.rs:35:26 + --> $DIR/eta.rs:36:26 | LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted | ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below` error: redundant closure - --> $DIR/eta.rs:42:27 + --> $DIR/eta.rs:43:27 | LL | let e = Some(1u8).map(|a| generic(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic` error: redundant closure - --> $DIR/eta.rs:94:51 + --> $DIR/eta.rs:95:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo` @@ -39,121 +39,121 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo()); = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings` error: redundant closure - --> $DIR/eta.rs:95:51 + --> $DIR/eta.rs:96:51 | LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo` error: redundant closure - --> $DIR/eta.rs:97:42 + --> $DIR/eta.rs:98:42 | LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear()); | ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear` error: redundant closure - --> $DIR/eta.rs:101:29 + --> $DIR/eta.rs:102:29 | LL | let e = Some("str").map(|s| s.to_string()); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string` error: redundant closure - --> $DIR/eta.rs:102:27 + --> $DIR/eta.rs:103:27 | LL | let e = Some('a').map(|s| s.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase` error: redundant closure - --> $DIR/eta.rs:104:65 + --> $DIR/eta.rs:105:65 | LL | let e: std::vec::Vec = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase` error: redundant closure - --> $DIR/eta.rs:167:22 + --> $DIR/eta.rs:168:22 | LL | requires_fn_once(|| x()); | ^^^^^^ help: replace the closure with the function itself: `x` error: redundant closure - --> $DIR/eta.rs:174:27 + --> $DIR/eta.rs:175:27 | LL | let a = Some(1u8).map(|a| foo_ptr(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr` error: redundant closure - --> $DIR/eta.rs:179:27 + --> $DIR/eta.rs:180:27 | LL | let a = Some(1u8).map(|a| closure(a)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure` error: redundant closure - --> $DIR/eta.rs:211:28 + --> $DIR/eta.rs:212:28 | LL | x.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> $DIR/eta.rs:212:28 + --> $DIR/eta.rs:213:28 | LL | y.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res` error: redundant closure - --> $DIR/eta.rs:213:28 + --> $DIR/eta.rs:214:28 | LL | z.into_iter().for_each(|x| add_to_res(x)); | ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res` error: redundant closure - --> $DIR/eta.rs:220:21 + --> $DIR/eta.rs:221:21 | LL | Some(1).map(|n| closure(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure` error: redundant closure - --> $DIR/eta.rs:224:21 + --> $DIR/eta.rs:225:21 | LL | Some(1).map(|n| in_loop(n)); | ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop` error: redundant closure - --> $DIR/eta.rs:317:18 + --> $DIR/eta.rs:318:18 | LL | takes_fn_mut(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> $DIR/eta.rs:320:19 + --> $DIR/eta.rs:321:19 | LL | takes_fn_once(|| f()); | ^^^^^^ help: replace the closure with the function itself: `&mut f` error: redundant closure - --> $DIR/eta.rs:324:26 + --> $DIR/eta.rs:325:26 | LL | move || takes_fn_mut(|| f_used_once()) | ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once` error: redundant closure - --> $DIR/eta.rs:336:19 + --> $DIR/eta.rs:337:19 | LL | array_opt.map(|a| a.as_slice()); | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice` error: redundant closure - --> $DIR/eta.rs:339:19 + --> $DIR/eta.rs:340:19 | LL | slice_opt.map(|s| s.len()); | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len` error: redundant closure - --> $DIR/eta.rs:342:17 + --> $DIR/eta.rs:343:17 | LL | ptr_opt.map(|p| p.is_null()); | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null` error: redundant closure - --> $DIR/eta.rs:346:17 + --> $DIR/eta.rs:347:17 | LL | dyn_opt.map(|d| d.method_on_dyn()); | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `::method_on_dyn` diff --git a/tests/ui/flat_map_option.fixed b/tests/ui/flat_map_option.fixed index eeab864c42ff..dbb625d27209 100644 --- a/tests/ui/flat_map_option.fixed +++ b/tests/ui/flat_map_option.fixed @@ -1,6 +1,10 @@ //@run-rustfix #![warn(clippy::flat_map_option)] -#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] +#![allow( + clippy::iter_on_single_items, + clippy::redundant_closure, + clippy::unnecessary_filter_map +)] fn main() { // yay diff --git a/tests/ui/flat_map_option.rs b/tests/ui/flat_map_option.rs index ebc389f7f029..570172d24ed9 100644 --- a/tests/ui/flat_map_option.rs +++ b/tests/ui/flat_map_option.rs @@ -1,6 +1,10 @@ //@run-rustfix #![warn(clippy::flat_map_option)] -#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] +#![allow( + clippy::iter_on_single_items, + clippy::redundant_closure, + clippy::unnecessary_filter_map +)] fn main() { // yay diff --git a/tests/ui/flat_map_option.stderr b/tests/ui/flat_map_option.stderr index a9d8056dee97..c4cac0ec36a6 100644 --- a/tests/ui/flat_map_option.stderr +++ b/tests/ui/flat_map_option.stderr @@ -1,5 +1,5 @@ error: used `flat_map` where `filter_map` could be used instead - --> $DIR/flat_map_option.rs:8:24 + --> $DIR/flat_map_option.rs:12:24 | LL | let _ = [1].iter().flat_map(c); | ^^^^^^^^ help: try: `filter_map` @@ -7,7 +7,7 @@ LL | let _ = [1].iter().flat_map(c); = note: `-D clippy::flat-map-option` implied by `-D warnings` error: used `flat_map` where `filter_map` could be used instead - --> $DIR/flat_map_option.rs:9:24 + --> $DIR/flat_map_option.rs:13:24 | LL | let _ = [1].iter().flat_map(Some); | ^^^^^^^^ help: try: `filter_map` diff --git a/tests/ui/issue_2356.fixed b/tests/ui/issue_2356.fixed index a69f5ebdc08c..004d69b8477d 100644 --- a/tests/ui/issue_2356.fixed +++ b/tests/ui/issue_2356.fixed @@ -1,7 +1,7 @@ //@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::iter_on_empty_collections, clippy::uninlined_format_args)] use std::iter::Iterator; diff --git a/tests/ui/issue_2356.rs b/tests/ui/issue_2356.rs index 50e1bce1f8c9..ae119ad83398 100644 --- a/tests/ui/issue_2356.rs +++ b/tests/ui/issue_2356.rs @@ -1,7 +1,7 @@ //@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::iter_on_empty_collections, clippy::uninlined_format_args)] use std::iter::Iterator; diff --git a/tests/ui/iter_not_returning_iterator.rs b/tests/ui/iter_not_returning_iterator.rs index cce216fc649b..6ebb2b39a8e3 100644 --- a/tests/ui/iter_not_returning_iterator.rs +++ b/tests/ui/iter_not_returning_iterator.rs @@ -1,4 +1,5 @@ #![warn(clippy::iter_not_returning_iterator)] +#![allow(clippy::iter_on_empty_collections)] struct Data { begin: u32, diff --git a/tests/ui/iter_not_returning_iterator.stderr b/tests/ui/iter_not_returning_iterator.stderr index 44f029558369..333cc257bfae 100644 --- a/tests/ui/iter_not_returning_iterator.stderr +++ b/tests/ui/iter_not_returning_iterator.stderr @@ -1,5 +1,5 @@ error: this method is named `iter` but its return type does not implement `Iterator` - --> $DIR/iter_not_returning_iterator.rs:30:5 + --> $DIR/iter_not_returning_iterator.rs:31:5 | LL | fn iter(&self) -> Counter2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | fn iter(&self) -> Counter2 { = note: `-D clippy::iter-not-returning-iterator` implied by `-D warnings` error: this method is named `iter_mut` but its return type does not implement `Iterator` - --> $DIR/iter_not_returning_iterator.rs:34:5 + --> $DIR/iter_not_returning_iterator.rs:35:5 | LL | fn iter_mut(&self) -> Counter2 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this method is named `iter` but its return type does not implement `Iterator` - --> $DIR/iter_not_returning_iterator.rs:50:5 + --> $DIR/iter_not_returning_iterator.rs:51:5 | LL | fn iter(&self) -> Self::I; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/iter_on_empty_collections.fixed b/tests/ui/iter_on_empty_collections.fixed index 4616f0cdc45e..0558bb547590 100644 --- a/tests/ui/iter_on_empty_collections.fixed +++ b/tests/ui/iter_on_empty_collections.fixed @@ -10,27 +10,37 @@ fn array() { assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + let x: [u32; 0] = []; + x.iter().copied().chain(std::iter::empty()); + x.iter().copied().eq(std::iter::empty()); + x.iter().copied().ne(std::iter::empty()); + let x: Vec = vec![]; + x.iter().copied().chain(std::iter::empty()); + x.iter().copied().eq(std::iter::empty()); + x.iter().copied().ne(std::iter::empty()); + // Don't trigger on non-iter methods let _: Option = None.clone(); let _: [String; 0] = [].clone(); + // FIXME: See line 135 in `single_or_empty_collections_iter` // Don't trigger on match or if branches - let _ = match 123 { - 123 => [].iter(), - _ => ["test"].iter(), - }; + // let _ = match 123 { + // 123 => [].iter(), + // _ => ["test"].iter(), + // }; - let _ = if false { ["test"].iter() } else { [].iter() }; + // let _ = if false { ["test"].iter() } else { [].iter() }; } macro_rules! in_macros { () => { - assert_eq!([].into_iter().next(), Option::::None); - assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); - assert_eq!([].iter().next(), Option::<&i32>::None); - assert_eq!(None.into_iter().next(), Option::::None); - assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); - assert_eq!(None.iter().next(), Option::<&i32>::None); + assert_eq!(std::iter::empty().next(), Option::::None); + assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&i32>::None); + assert_eq!(std::iter::empty().next(), Option::::None); + assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None); + assert_eq!(std::iter::empty().next(), Option::<&i32>::None); }; } diff --git a/tests/ui/iter_on_empty_collections.rs b/tests/ui/iter_on_empty_collections.rs index 81cc7265e11e..48aafe31e683 100644 --- a/tests/ui/iter_on_empty_collections.rs +++ b/tests/ui/iter_on_empty_collections.rs @@ -10,17 +10,27 @@ fn array() { assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); assert_eq!(None.iter().next(), Option::<&i32>::None); + let x: [u32; 0] = []; + x.iter().copied().chain([]); + x.iter().copied().eq([]); + x.iter().copied().ne([]); + let x: Vec = vec![]; + x.iter().copied().chain(vec![]); + x.iter().copied().eq(vec![]); + x.iter().copied().ne(vec![]); + // Don't trigger on non-iter methods let _: Option = None.clone(); let _: [String; 0] = [].clone(); + // FIXME: See line 135 in `single_or_empty_collections_iter` // Don't trigger on match or if branches - let _ = match 123 { - 123 => [].iter(), - _ => ["test"].iter(), - }; + // let _ = match 123 { + // 123 => [].iter(), + // _ => ["test"].iter(), + // }; - let _ = if false { ["test"].iter() } else { [].iter() }; + // let _ = if false { ["test"].iter() } else { [].iter() }; } macro_rules! in_macros { diff --git a/tests/ui/iter_on_empty_collections.stderr b/tests/ui/iter_on_empty_collections.stderr index cbd611769569..0cae2d3c8455 100644 --- a/tests/ui/iter_on_empty_collections.stderr +++ b/tests/ui/iter_on_empty_collections.stderr @@ -1,40 +1,154 @@ -error: `into_iter` call on an empty collection +error: usage of `[T; 0]` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:6:16 | LL | assert_eq!([].into_iter().next(), Option::::None); - | ^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + | ^^------------ + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` | = note: `-D clippy::iter-on-empty-collections` implied by `-D warnings` -error: `iter_mut` call on an empty collection +error: usage of `[T; 0]` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:7:16 | LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); - | ^^^^^^^^^^^^^ help: try: `std::iter::empty()` + | ^^----------- + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` -error: `iter` call on an empty collection +error: usage of `[T; 0]` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:8:16 | LL | assert_eq!([].iter().next(), Option::<&i32>::None); - | ^^^^^^^^^ help: try: `std::iter::empty()` + | ^^------- + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` -error: `into_iter` call on an empty collection +error: usage of `None` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:9:16 | LL | assert_eq!(None.into_iter().next(), Option::::None); - | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + | ^^^^------------ + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` -error: `iter_mut` call on an empty collection +error: usage of `None` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:10:16 | LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); - | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()` + | ^^^^----------- + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` -error: `iter` call on an empty collection +error: usage of `None` to create an empty iterator --> $DIR/iter_on_empty_collections.rs:11:16 | LL | assert_eq!(None.iter().next(), Option::<&i32>::None); - | ^^^^^^^^^^^ help: try: `std::iter::empty()` + | ^^^^------- + | | + | help: use `std::iter::empty` instead: `std::iter::empty()` -error: aborting due to 6 previous errors +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:14:29 + | +LL | x.iter().copied().chain([]); + | ^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:15:26 + | +LL | x.iter().copied().eq([]); + | ^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:16:26 + | +LL | x.iter().copied().ne([]); + | ^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:18:29 + | +LL | x.iter().copied().chain(vec![]); + | ^^^^^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:19:26 + | +LL | x.iter().copied().eq(vec![]); + | ^^^^^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:20:26 + | +LL | x.iter().copied().ne(vec![]); + | ^^^^^^ help: use `std::iter::empty` instead: `std::iter::empty()` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!([].into_iter().next(), Option::::None); + | -------------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None); + | ------------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `[T; 0]` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!([].iter().next(), Option::<&i32>::None); + | --------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `None` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!(None.into_iter().next(), Option::::None); + | ---------------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `None` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None); + | --------------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `None` to create an empty iterator + --> $DIR/iter_on_empty_collections.rs:72:5 + | +LL | assert_eq!(None.iter().next(), Option::<&i32>::None); + | ----------- help: use `std::iter::empty` instead: `std::iter::empty()` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: aborting due to 18 previous errors diff --git a/tests/ui/iter_on_single_items.fixed b/tests/ui/iter_on_single_items.fixed index 80dbe454b470..01e1ef8ea41e 100644 --- a/tests/ui/iter_on_single_items.fixed +++ b/tests/ui/iter_on_single_items.fixed @@ -10,27 +10,37 @@ fn array() { assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); assert_eq!(std::iter::once(&123).next(), Some(&123)); + let x: [u32; 1] = [1]; + x.iter().copied().chain(std::iter::once(1)); + x.iter().copied().eq(std::iter::once(1)); + x.iter().copied().ne(std::iter::once(1)); + let x: Vec = vec![1]; + x.iter().copied().chain(std::iter::once(1)); + x.iter().copied().eq(std::iter::once(1)); + x.iter().copied().ne(std::iter::once(1)); + // Don't trigger on non-iter methods let _: Option = Some("test".to_string()).clone(); let _: [String; 1] = ["test".to_string()].clone(); + // FIXME: See line 135 in `single_or_empty_collections_iter` // Don't trigger on match or if branches - let _ = match 123 { - 123 => [].iter(), - _ => ["test"].iter(), - }; + // let _ = match 123 { + // 123 => [].iter(), + // _ => ["test"].iter(), + // }; - let _ = if false { ["test"].iter() } else { [].iter() }; + // let _ = if false { ["test"].iter() } else { [].iter() }; } macro_rules! in_macros { () => { - assert_eq!([123].into_iter().next(), Some(123)); - assert_eq!([123].iter_mut().next(), Some(&mut 123)); - assert_eq!([123].iter().next(), Some(&123)); - assert_eq!(Some(123).into_iter().next(), Some(123)); - assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); - assert_eq!(Some(123).iter().next(), Some(&123)); + assert_eq!(std::iter::once(123).next(), Some(123)); + assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + assert_eq!(std::iter::once(&123).next(), Some(&123)); + assert_eq!(std::iter::once(123).next(), Some(123)); + assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123)); + assert_eq!(std::iter::once(&123).next(), Some(&123)); }; } diff --git a/tests/ui/iter_on_single_items.rs b/tests/ui/iter_on_single_items.rs index 71c8c7a3f94c..2e4f2e8b8347 100644 --- a/tests/ui/iter_on_single_items.rs +++ b/tests/ui/iter_on_single_items.rs @@ -10,17 +10,27 @@ fn array() { assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); assert_eq!(Some(123).iter().next(), Some(&123)); + let x: [u32; 1] = [1]; + x.iter().copied().chain([1]); + x.iter().copied().eq([1]); + x.iter().copied().ne([1]); + let x: Vec = vec![1]; + x.iter().copied().chain(vec![1]); + x.iter().copied().eq(vec![1]); + x.iter().copied().ne(vec![1]); + // Don't trigger on non-iter methods let _: Option = Some("test".to_string()).clone(); let _: [String; 1] = ["test".to_string()].clone(); + // FIXME: See line 135 in `single_or_empty_collections_iter` // Don't trigger on match or if branches - let _ = match 123 { - 123 => [].iter(), - _ => ["test"].iter(), - }; + // let _ = match 123 { + // 123 => [].iter(), + // _ => ["test"].iter(), + // }; - let _ = if false { ["test"].iter() } else { [].iter() }; + // let _ = if false { ["test"].iter() } else { [].iter() }; } macro_rules! in_macros { diff --git a/tests/ui/iter_on_single_items.stderr b/tests/ui/iter_on_single_items.stderr index d6c547116363..ac8c06f48918 100644 --- a/tests/ui/iter_on_single_items.stderr +++ b/tests/ui/iter_on_single_items.stderr @@ -1,40 +1,154 @@ -error: `into_iter` call on a collection with only one item +error: usage of `[T; 1]` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:6:16 | LL | assert_eq!([123].into_iter().next(), Some(123)); - | ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)` + | ^^^^^------------ + | | + | help: use `std::iter::once` instead: `std::iter::once(123)` | = note: `-D clippy::iter-on-single-items` implied by `-D warnings` -error: `iter_mut` call on a collection with only one item +error: usage of `[T; 1]` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:7:16 | LL | assert_eq!([123].iter_mut().next(), Some(&mut 123)); - | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` + | ^^^^^----------- + | | + | help: use `std::iter::once` instead: `std::iter::once(&mut 123)` -error: `iter` call on a collection with only one item +error: usage of `[T; 1]` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:8:16 | LL | assert_eq!([123].iter().next(), Some(&123)); - | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)` + | ^^^^^------- + | | + | help: use `std::iter::once` instead: `std::iter::once(&123)` -error: `into_iter` call on a collection with only one item +error: usage of `Some` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:9:16 | LL | assert_eq!(Some(123).into_iter().next(), Some(123)); - | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)` + | ^^^^^^^^^------------ + | | + | help: use `std::iter::once` instead: `std::iter::once(123)` -error: `iter_mut` call on a collection with only one item +error: usage of `Some` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:10:16 | LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); - | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)` + | ^^^^^^^^^----------- + | | + | help: use `std::iter::once` instead: `std::iter::once(&mut 123)` -error: `iter` call on a collection with only one item +error: usage of `Some` to create an iterator with only one element --> $DIR/iter_on_single_items.rs:11:16 | LL | assert_eq!(Some(123).iter().next(), Some(&123)); - | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)` + | ^^^^^^^^^------- + | | + | help: use `std::iter::once` instead: `std::iter::once(&123)` -error: aborting due to 6 previous errors +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:14:29 + | +LL | x.iter().copied().chain([1]); + | ^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:15:26 + | +LL | x.iter().copied().eq([1]); + | ^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:16:26 + | +LL | x.iter().copied().ne([1]); + | ^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:18:29 + | +LL | x.iter().copied().chain(vec![1]); + | ^^^^^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:19:26 + | +LL | x.iter().copied().eq(vec![1]); + | ^^^^^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:20:26 + | +LL | x.iter().copied().ne(vec![1]); + | ^^^^^^^ help: use `std::iter::once` instead: `std::iter::once(1)` + | + = note: this method is generic over `Iterator` + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!([123].into_iter().next(), Some(123)); + | ----------------- help: use `std::iter::once` instead: `std::iter::once(123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!([123].iter_mut().next(), Some(&mut 123)); + | ---------------- help: use `std::iter::once` instead: `std::iter::once(&mut 123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `[T; 1]` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!([123].iter().next(), Some(&123)); + | ------------ help: use `std::iter::once` instead: `std::iter::once(&123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `Some` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!(Some(123).into_iter().next(), Some(123)); + | --------------------- help: use `std::iter::once` instead: `std::iter::once(123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `Some` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123)); + | -------------------- help: use `std::iter::once` instead: `std::iter::once(&mut 123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: usage of `Some` to create an iterator with only one element + --> $DIR/iter_on_single_items.rs:72:5 + | +LL | assert_eq!(Some(123).iter().next(), Some(&123)); + | ---------------- help: use `std::iter::once` instead: `std::iter::once(&123)` +... +LL | in_macros!(); + | ^^^^^^^^^^^^ + +error: aborting due to 18 previous errors diff --git a/tests/ui/manual_map_option.fixed b/tests/ui/manual_map_option.fixed index e8ff65cad6aa..20d4e100e40d 100644 --- a/tests/ui/manual_map_option.fixed +++ b/tests/ui/manual_map_option.fixed @@ -2,6 +2,7 @@ #![warn(clippy::manual_map)] #![allow( + clippy::iter_on_single_items, clippy::no_effect, clippy::map_identity, clippy::unit_arg, diff --git a/tests/ui/manual_map_option.rs b/tests/ui/manual_map_option.rs index b06a96451ce7..02ae316111ca 100644 --- a/tests/ui/manual_map_option.rs +++ b/tests/ui/manual_map_option.rs @@ -2,6 +2,7 @@ #![warn(clippy::manual_map)] #![allow( + clippy::iter_on_single_items, clippy::no_effect, clippy::map_identity, clippy::unit_arg, diff --git a/tests/ui/manual_map_option.stderr b/tests/ui/manual_map_option.stderr index cdc2c0e62a9b..4392d585ed20 100644 --- a/tests/ui/manual_map_option.stderr +++ b/tests/ui/manual_map_option.stderr @@ -1,5 +1,5 @@ error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:15:5 + --> $DIR/manual_map_option.rs:16:5 | LL | / match Some(0) { LL | | Some(_) => Some(2), @@ -10,7 +10,7 @@ LL | | }; = note: `-D clippy::manual-map` implied by `-D warnings` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:20:5 + --> $DIR/manual_map_option.rs:21:5 | LL | / match Some(0) { LL | | Some(x) => Some(x + 1), @@ -19,7 +19,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + 1)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:25:5 + --> $DIR/manual_map_option.rs:26:5 | LL | / match Some("") { LL | | Some(x) => Some(x.is_empty()), @@ -28,7 +28,7 @@ LL | | }; | |_____^ help: try this: `Some("").map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:30:5 + --> $DIR/manual_map_option.rs:31:5 | LL | / if let Some(x) = Some(0) { LL | | Some(!x) @@ -38,7 +38,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| !x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:37:5 + --> $DIR/manual_map_option.rs:38:5 | LL | / match Some(0) { LL | | Some(x) => { Some(std::convert::identity(x)) } @@ -47,7 +47,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(std::convert::identity)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:42:5 + --> $DIR/manual_map_option.rs:43:5 | LL | / match Some(&String::new()) { LL | | Some(x) => Some(str::len(x)), @@ -56,7 +56,7 @@ LL | | }; | |_____^ help: try this: `Some(&String::new()).map(|x| str::len(x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:52:5 + --> $DIR/manual_map_option.rs:53:5 | LL | / match &Some([0, 1]) { LL | | Some(x) => Some(x[0]), @@ -65,7 +65,7 @@ LL | | }; | |_____^ help: try this: `Some([0, 1]).as_ref().map(|x| x[0])` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:57:5 + --> $DIR/manual_map_option.rs:58:5 | LL | / match &Some(0) { LL | | &Some(x) => Some(x * 2), @@ -74,7 +74,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x * 2)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:62:5 + --> $DIR/manual_map_option.rs:63:5 | LL | / match Some(String::new()) { LL | | Some(ref x) => Some(x.is_empty()), @@ -83,7 +83,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:67:5 + --> $DIR/manual_map_option.rs:68:5 | LL | / match &&Some(String::new()) { LL | | Some(x) => Some(x.len()), @@ -92,7 +92,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:72:5 + --> $DIR/manual_map_option.rs:73:5 | LL | / match &&Some(0) { LL | | &&Some(x) => Some(x + x), @@ -101,7 +101,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| x + x)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:85:9 + --> $DIR/manual_map_option.rs:86:9 | LL | / match &mut Some(String::new()) { LL | | Some(x) => Some(x.push_str("")), @@ -110,7 +110,7 @@ LL | | }; | |_________^ help: try this: `Some(String::new()).as_mut().map(|x| x.push_str(""))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:91:5 + --> $DIR/manual_map_option.rs:92:5 | LL | / match &mut Some(String::new()) { LL | | Some(ref x) => Some(x.len()), @@ -119,7 +119,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.len())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:96:5 + --> $DIR/manual_map_option.rs:97:5 | LL | / match &mut &Some(String::new()) { LL | | Some(x) => Some(x.is_empty()), @@ -128,7 +128,7 @@ LL | | }; | |_____^ help: try this: `Some(String::new()).as_ref().map(|x| x.is_empty())` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:101:5 + --> $DIR/manual_map_option.rs:102:5 | LL | / match Some((0, 1, 2)) { LL | | Some((x, y, z)) => Some(x + y + z), @@ -137,7 +137,7 @@ LL | | }; | |_____^ help: try this: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:106:5 + --> $DIR/manual_map_option.rs:107:5 | LL | / match Some([1, 2, 3]) { LL | | Some([first, ..]) => Some(first), @@ -146,7 +146,7 @@ LL | | }; | |_____^ help: try this: `Some([1, 2, 3]).map(|[first, ..]| first)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:111:5 + --> $DIR/manual_map_option.rs:112:5 | LL | / match &Some((String::new(), "test")) { LL | | Some((x, y)) => Some((y, x)), @@ -155,7 +155,7 @@ LL | | }; | |_____^ help: try this: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:169:5 + --> $DIR/manual_map_option.rs:170:5 | LL | / match Some(0) { LL | | Some(x) => Some(vec![x]), @@ -164,7 +164,7 @@ LL | | }; | |_____^ help: try this: `Some(0).map(|x| vec![x])` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:174:5 + --> $DIR/manual_map_option.rs:175:5 | LL | / match option_env!("") { LL | | Some(x) => Some(String::from(x)), @@ -173,7 +173,7 @@ LL | | }; | |_____^ help: try this: `option_env!("").map(String::from)` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:194:12 + --> $DIR/manual_map_option.rs:195:12 | LL | } else if let Some(x) = Some(0) { | ____________^ @@ -184,7 +184,7 @@ LL | | }; | |_____^ help: try this: `{ Some(0).map(|x| x + 1) }` error: manual implementation of `Option::map` - --> $DIR/manual_map_option.rs:202:12 + --> $DIR/manual_map_option.rs:203:12 | LL | } else if let Some(x) = Some(0) { | ____________^ diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed index 50c0eb1a8108..c05feaf03a27 100644 --- a/tests/ui/map_clone.fixed +++ b/tests/ui/map_clone.fixed @@ -3,6 +3,7 @@ #![allow( clippy::clone_on_copy, clippy::iter_cloned_collect, + clippy::iter_on_single_items, clippy::many_single_char_names, clippy::redundant_clone, clippy::useless_vec diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs index 91a084f2844d..1929bfed2a91 100644 --- a/tests/ui/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -3,6 +3,7 @@ #![allow( clippy::clone_on_copy, clippy::iter_cloned_collect, + clippy::iter_on_single_items, clippy::many_single_char_names, clippy::redundant_clone, clippy::useless_vec diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr index d768af1f48c9..6a118b7989bf 100644 --- a/tests/ui/map_clone.stderr +++ b/tests/ui/map_clone.stderr @@ -1,5 +1,5 @@ error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:12:22 + --> $DIR/map_clone.rs:13:22 | LL | let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![5_i8; 6].iter().copied()` @@ -7,31 +7,31 @@ LL | let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); = note: `-D clippy::map-clone` implied by `-D warnings` error: you are using an explicit closure for cloning elements - --> $DIR/map_clone.rs:13:26 + --> $DIR/map_clone.rs:14:26 | LL | let _: Vec = vec![String::new()].iter().map(|x| x.clone()).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `vec![String::new()].iter().cloned()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:14:23 + --> $DIR/map_clone.rs:15:23 | LL | let _: Vec = vec![42, 43].iter().map(|&x| x).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![42, 43].iter().copied()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:16:26 + --> $DIR/map_clone.rs:17:26 | LL | let _: Option = Some(&16).map(|b| *b); | ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&16).copied()` error: you are using an explicit closure for copying elements - --> $DIR/map_clone.rs:17:25 + --> $DIR/map_clone.rs:18:25 | LL | let _: Option = Some(&1).map(|x| x.clone()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&1).copied()` error: you are needlessly cloning iterator elements - --> $DIR/map_clone.rs:28:29 + --> $DIR/map_clone.rs:29:29 | LL | let _ = std::env::args().map(|v| v.clone()); | ^^^^^^^^^^^^^^^^^^^ help: remove the `map` call diff --git a/tests/ui/needless_collect_indirect.rs b/tests/ui/needless_collect_indirect.rs index d3d856c2c659..29962dc30666 100644 --- a/tests/ui/needless_collect_indirect.rs +++ b/tests/ui/needless_collect_indirect.rs @@ -1,5 +1,5 @@ #![allow(clippy::uninlined_format_args, clippy::useless_vec)] -#![allow(clippy::needless_if, clippy::uninlined_format_args)] +#![allow(clippy::iter_on_single_items, clippy::needless_if, clippy::uninlined_format_args)] #![warn(clippy::needless_collect)] use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; diff --git a/tests/ui/option_filter_map.fixed b/tests/ui/option_filter_map.fixed index 93c250cfa735..77cce00f8540 100644 --- a/tests/ui/option_filter_map.fixed +++ b/tests/ui/option_filter_map.fixed @@ -1,6 +1,6 @@ //@run-rustfix #![warn(clippy::option_filter_map)] -#![allow(clippy::map_flatten)] +#![allow(clippy::iter_on_single_items, clippy::map_flatten)] fn main() { let _ = Some(Some(1)).flatten(); diff --git a/tests/ui/option_filter_map.rs b/tests/ui/option_filter_map.rs index 2c5f03250b98..57c8df5b9ac9 100644 --- a/tests/ui/option_filter_map.rs +++ b/tests/ui/option_filter_map.rs @@ -1,6 +1,6 @@ //@run-rustfix #![warn(clippy::option_filter_map)] -#![allow(clippy::map_flatten)] +#![allow(clippy::iter_on_single_items, clippy::map_flatten)] fn main() { let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap); diff --git a/tests/ui/search_is_some_fixable_none.fixed b/tests/ui/search_is_some_fixable_none.fixed index 08fb87cb306e..f68a5f9dd92c 100644 --- a/tests/ui/search_is_some_fixable_none.fixed +++ b/tests/ui/search_is_some_fixable_none.fixed @@ -1,5 +1,10 @@ //@run-rustfix -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow( + dead_code, + clippy::explicit_auto_deref, + clippy::iter_on_single_items, + clippy::useless_vec +)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_none.rs b/tests/ui/search_is_some_fixable_none.rs index ec3386933a61..7bdce4cd99d6 100644 --- a/tests/ui/search_is_some_fixable_none.rs +++ b/tests/ui/search_is_some_fixable_none.rs @@ -1,5 +1,10 @@ //@run-rustfix -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow( + dead_code, + clippy::explicit_auto_deref, + clippy::iter_on_single_items, + clippy::useless_vec +)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_none.stderr b/tests/ui/search_is_some_fixable_none.stderr index 933ce5cf42d2..598fccca49b2 100644 --- a/tests/ui/search_is_some_fixable_none.stderr +++ b/tests/ui/search_is_some_fixable_none.stderr @@ -1,5 +1,5 @@ error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:10:13 + --> $DIR/search_is_some_fixable_none.rs:15:13 | LL | let _ = v.iter().find(|&x| *x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x < 0)` @@ -7,49 +7,49 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_none(); = note: `-D clippy::search-is-some` implied by `-D warnings` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:11:13 + --> $DIR/search_is_some_fixable_none.rs:16:13 | LL | let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| **y == x)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:12:13 + --> $DIR/search_is_some_fixable_none.rs:17:13 | LL | let _ = (0..1).find(|x| *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:13:13 + --> $DIR/search_is_some_fixable_none.rs:18:13 | LL | let _ = v.iter().find(|x| **x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:14:13 + --> $DIR/search_is_some_fixable_none.rs:19:13 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:15:13 + --> $DIR/search_is_some_fixable_none.rs:20:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:16:13 + --> $DIR/search_is_some_fixable_none.rs:21:13 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:17:13 + --> $DIR/search_is_some_fixable_none.rs:22:13 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:18:13 + --> $DIR/search_is_some_fixable_none.rs:23:13 | LL | let _ = (1..3) | _____________^ @@ -58,91 +58,91 @@ LL | | .is_none(); | |__________________^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_none()` after searching an `Iterator` with `position` - --> $DIR/search_is_some_fixable_none.rs:23:13 + --> $DIR/search_is_some_fixable_none.rs:28:13 | LL | let _ = v.iter().position(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after searching an `Iterator` with `rposition` - --> $DIR/search_is_some_fixable_none.rs:26:13 + --> $DIR/search_is_some_fixable_none.rs:31:13 | LL | let _ = v.iter().rposition(|&x| x < 0).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:32:13 + --> $DIR/search_is_some_fixable_none.rs:37:13 | LL | let _ = "hello world".find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains("world")` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:33:13 + --> $DIR/search_is_some_fixable_none.rs:38:13 | LL | let _ = "hello world".find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:34:13 + --> $DIR/search_is_some_fixable_none.rs:39:13 | LL | let _ = "hello world".find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:36:13 + --> $DIR/search_is_some_fixable_none.rs:41:13 | LL | let _ = s1.find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains("world")` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:37:13 + --> $DIR/search_is_some_fixable_none.rs:42:13 | LL | let _ = s1.find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:38:13 + --> $DIR/search_is_some_fixable_none.rs:43:13 | LL | let _ = s1.find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2[2..])` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:40:13 + --> $DIR/search_is_some_fixable_none.rs:45:13 | LL | let _ = s1[2..].find("world").is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains("world")` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:41:13 + --> $DIR/search_is_some_fixable_none.rs:46:13 | LL | let _ = s1[2..].find(&s2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2)` error: called `is_none()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_none.rs:42:13 + --> $DIR/search_is_some_fixable_none.rs:47:13 | LL | let _ = s1[2..].find(&s2[2..]).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2[2..])` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:58:25 + --> $DIR/search_is_some_fixable_none.rs:63:25 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == &cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:74:30 + --> $DIR/search_is_some_fixable_none.rs:79:30 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == cc)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:85:17 + --> $DIR/search_is_some_fixable_none.rs:90:17 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:88:17 + --> $DIR/search_is_some_fixable_none.rs:93:17 | LL | let _ = vfoo | _________________^ @@ -158,55 +158,55 @@ LL ~ .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2); | error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:96:17 + --> $DIR/search_is_some_fixable_none.rs:101:17 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|a| a[0] == 42)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:102:17 + --> $DIR/search_is_some_fixable_none.rs:107:17 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:120:17 + --> $DIR/search_is_some_fixable_none.rs:125:17 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:121:17 + --> $DIR/search_is_some_fixable_none.rs:126:17 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:124:17 + --> $DIR/search_is_some_fixable_none.rs:129:17 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:125:17 + --> $DIR/search_is_some_fixable_none.rs:130:17 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| deref_enough(*x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:128:17 + --> $DIR/search_is_some_fixable_none.rs:133:17 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:130:17 + --> $DIR/search_is_some_fixable_none.rs:135:17 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| arg_no_deref(&x))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:150:17 + --> $DIR/search_is_some_fixable_none.rs:155:17 | LL | let _ = vfoo | _________________^ @@ -222,61 +222,61 @@ LL ~ .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] | error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:166:17 + --> $DIR/search_is_some_fixable_none.rs:171:17 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.inner[0].bar == 2)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:171:17 + --> $DIR/search_is_some_fixable_none.rs:176:17 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|x| (**x)[0] == 9)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:184:17 + --> $DIR/search_is_some_fixable_none.rs:189:17 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.by_ref(&v.bar))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:188:17 + --> $DIR/search_is_some_fixable_none.rs:193:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:189:17 + --> $DIR/search_is_some_fixable_none.rs:194:17 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:208:17 + --> $DIR/search_is_some_fixable_none.rs:213:17 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| s[0].is_empty())` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:209:17 + --> $DIR/search_is_some_fixable_none.rs:214:17 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| test_string_1(&s[0]))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:218:17 + --> $DIR/search_is_some_fixable_none.rs:223:17 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| fp.field.is_power_of_two())` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:219:17 + --> $DIR/search_is_some_fixable_none.rs:224:17 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_1(fp.field))` error: called `is_none()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_none.rs:220:17 + --> $DIR/search_is_some_fixable_none.rs:225:17 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_2(*fp.field))` diff --git a/tests/ui/search_is_some_fixable_some.fixed b/tests/ui/search_is_some_fixable_some.fixed index aa16f9da037d..ceeaab94ad11 100644 --- a/tests/ui/search_is_some_fixable_some.fixed +++ b/tests/ui/search_is_some_fixable_some.fixed @@ -1,5 +1,11 @@ //@run-rustfix -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow( + dead_code, + clippy::explicit_auto_deref, + clippy::iter_on_empty_collections, + clippy::iter_on_single_items, + clippy::useless_vec +)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.rs b/tests/ui/search_is_some_fixable_some.rs index aeb6f118bede..df39b670dfde 100644 --- a/tests/ui/search_is_some_fixable_some.rs +++ b/tests/ui/search_is_some_fixable_some.rs @@ -1,5 +1,11 @@ //@run-rustfix -#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec)] +#![allow( + dead_code, + clippy::explicit_auto_deref, + clippy::iter_on_empty_collections, + clippy::iter_on_single_items, + clippy::useless_vec +)] #![warn(clippy::search_is_some)] fn main() { diff --git a/tests/ui/search_is_some_fixable_some.stderr b/tests/ui/search_is_some_fixable_some.stderr index c5c3c92c9182..e592bf6d969f 100644 --- a/tests/ui/search_is_some_fixable_some.stderr +++ b/tests/ui/search_is_some_fixable_some.stderr @@ -1,5 +1,5 @@ error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:10:22 + --> $DIR/search_is_some_fixable_some.rs:16:22 | LL | let _ = v.iter().find(|&x| *x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x < 0)` @@ -7,49 +7,49 @@ LL | let _ = v.iter().find(|&x| *x < 0).is_some(); = note: `-D clippy::search-is-some` implied by `-D warnings` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:11:20 + --> $DIR/search_is_some_fixable_some.rs:17:20 | LL | let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| **y == x)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:12:20 + --> $DIR/search_is_some_fixable_some.rs:18:20 | LL | let _ = (0..1).find(|x| *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:13:22 + --> $DIR/search_is_some_fixable_some.rs:19:22 | LL | let _ = v.iter().find(|x| **x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:14:20 + --> $DIR/search_is_some_fixable_some.rs:20:20 | LL | let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 1 || x == 3 || x == 5)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:15:20 + --> $DIR/search_is_some_fixable_some.rs:21:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:16:20 + --> $DIR/search_is_some_fixable_some.rs:22:20 | LL | let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0 || [1, 2, 3].contains(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:17:20 + --> $DIR/search_is_some_fixable_some.rs:23:20 | LL | let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:19:10 + --> $DIR/search_is_some_fixable_some.rs:25:10 | LL | .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1) | __________^ @@ -57,91 +57,91 @@ LL | | .is_some(); | |__________________^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)` error: called `is_some()` after searching an `Iterator` with `position` - --> $DIR/search_is_some_fixable_some.rs:23:22 + --> $DIR/search_is_some_fixable_some.rs:29:22 | LL | let _ = v.iter().position(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)` error: called `is_some()` after searching an `Iterator` with `rposition` - --> $DIR/search_is_some_fixable_some.rs:26:22 + --> $DIR/search_is_some_fixable_some.rs:32:22 | LL | let _ = v.iter().rposition(|&x| x < 0).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:31:27 + --> $DIR/search_is_some_fixable_some.rs:37:27 | LL | let _ = "hello world".find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:32:27 + --> $DIR/search_is_some_fixable_some.rs:38:27 | LL | let _ = "hello world".find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:33:27 + --> $DIR/search_is_some_fixable_some.rs:39:27 | LL | let _ = "hello world".find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:35:16 + --> $DIR/search_is_some_fixable_some.rs:41:16 | LL | let _ = s1.find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:36:16 + --> $DIR/search_is_some_fixable_some.rs:42:16 | LL | let _ = s1.find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:37:16 + --> $DIR/search_is_some_fixable_some.rs:43:16 | LL | let _ = s1.find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:39:21 + --> $DIR/search_is_some_fixable_some.rs:45:21 | LL | let _ = s1[2..].find("world").is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:40:21 + --> $DIR/search_is_some_fixable_some.rs:46:21 | LL | let _ = s1[2..].find(&s2).is_some(); | ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)` error: called `is_some()` after calling `find()` on a string - --> $DIR/search_is_some_fixable_some.rs:41:21 + --> $DIR/search_is_some_fixable_some.rs:47:21 | LL | let _ = s1[2..].find(&s2[2..]).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:57:44 + --> $DIR/search_is_some_fixable_some.rs:63:44 | LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == &cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:73:49 + --> $DIR/search_is_some_fixable_some.rs:79:49 | LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == cc)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:84:29 + --> $DIR/search_is_some_fixable_some.rs:90:29 | LL | let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:89:14 + --> $DIR/search_is_some_fixable_some.rs:95:14 | LL | .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2) | ______________^ @@ -149,55 +149,55 @@ LL | | .is_some(); | |______________________^ help: use `any()` instead: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:95:29 + --> $DIR/search_is_some_fixable_some.rs:101:29 | LL | let _ = vfoo.iter().find(|a| a[0] == 42).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|a| a[0] == 42)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:101:29 + --> $DIR/search_is_some_fixable_some.rs:107:29 | LL | let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:119:30 + --> $DIR/search_is_some_fixable_some.rs:125:30 | LL | let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|ppp_x: &&u32| please(ppp_x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:120:50 + --> $DIR/search_is_some_fixable_some.rs:126:50 | LL | let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s.len() == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:123:26 + --> $DIR/search_is_some_fixable_some.rs:129:26 | LL | let _ = v.iter().find(|x| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:124:26 + --> $DIR/search_is_some_fixable_some.rs:130:26 | LL | let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| deref_enough(*x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:127:26 + --> $DIR/search_is_some_fixable_some.rs:133:26 | LL | let _ = v.iter().find(|x| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:129:26 + --> $DIR/search_is_some_fixable_some.rs:135:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:151:14 + --> $DIR/search_is_some_fixable_some.rs:157:14 | LL | .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2) | ______________^ @@ -205,85 +205,85 @@ LL | | .is_some(); | |______________________^ help: use `any()` instead: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:165:29 + --> $DIR/search_is_some_fixable_some.rs:171:29 | LL | let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.inner[0].bar == 2)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:170:29 + --> $DIR/search_is_some_fixable_some.rs:176:29 | LL | let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| (**x)[0] == 9)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:183:29 + --> $DIR/search_is_some_fixable_some.rs:189:29 | LL | let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.by_ref(&v.bar))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:187:55 + --> $DIR/search_is_some_fixable_some.rs:193:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:188:55 + --> $DIR/search_is_some_fixable_some.rs:194:55 | LL | let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:207:26 + --> $DIR/search_is_some_fixable_some.rs:213:26 | LL | let _ = v.iter().find(|s| s[0].is_empty()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s[0].is_empty())` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:208:26 + --> $DIR/search_is_some_fixable_some.rs:214:26 | LL | let _ = v.iter().find(|s| test_string_1(&s[0])).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| test_string_1(&s[0]))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:217:26 + --> $DIR/search_is_some_fixable_some.rs:223:26 | LL | let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| fp.field.is_power_of_two())` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:218:26 + --> $DIR/search_is_some_fixable_some.rs:224:26 | LL | let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_1(fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:219:26 + --> $DIR/search_is_some_fixable_some.rs:225:26 | LL | let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_2(*fp.field))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:234:18 + --> $DIR/search_is_some_fixable_some.rs:240:18 | LL | v.iter().find(|x: &&u32| func(x)).is_some() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| func(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:243:26 + --> $DIR/search_is_some_fixable_some.rs:249:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_impl(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:246:26 + --> $DIR/search_is_some_fixable_some.rs:252:26 | LL | let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_dyn(&x))` error: called `is_some()` after searching an `Iterator` with `find` - --> $DIR/search_is_some_fixable_some.rs:249:26 + --> $DIR/search_is_some_fixable_some.rs:255:26 | LL | let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| (*arg_no_deref_dyn)(&x))` diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed index 598f259415da..5ad3fc0a42cb 100644 --- a/tests/ui/single_element_loop.fixed +++ b/tests/ui/single_element_loop.fixed @@ -1,7 +1,7 @@ //@run-rustfix // Tests from for_loop.rs that don't have suggestions -#![allow(clippy::single_range_in_vec_init)] +#![allow(clippy::iter_on_single_items, clippy::single_range_in_vec_init)] #[warn(clippy::single_element_loop)] fn main() { diff --git a/tests/ui/single_element_loop.rs b/tests/ui/single_element_loop.rs index 3fc461735a49..71823563bf85 100644 --- a/tests/ui/single_element_loop.rs +++ b/tests/ui/single_element_loop.rs @@ -1,7 +1,7 @@ //@run-rustfix // Tests from for_loop.rs that don't have suggestions -#![allow(clippy::single_range_in_vec_init)] +#![allow(clippy::iter_on_single_items, clippy::single_range_in_vec_init)] #[warn(clippy::single_element_loop)] fn main() { diff --git a/tests/ui/try_err.fixed b/tests/ui/try_err.fixed index 1816740870ad..7eb3b88faaf2 100644 --- a/tests/ui/try_err.fixed +++ b/tests/ui/try_err.fixed @@ -2,7 +2,11 @@ //@aux-build:proc_macros.rs:proc-macro #![deny(clippy::try_err)] -#![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] +#![allow( + clippy::iter_on_single_items, + clippy::unnecessary_wraps, + clippy::needless_question_mark +)] extern crate proc_macros; use proc_macros::{external, inline_macros}; diff --git a/tests/ui/try_err.rs b/tests/ui/try_err.rs index 0e47c4d023ef..401c4ffb9e32 100644 --- a/tests/ui/try_err.rs +++ b/tests/ui/try_err.rs @@ -2,7 +2,11 @@ //@aux-build:proc_macros.rs:proc-macro #![deny(clippy::try_err)] -#![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] +#![allow( + clippy::iter_on_single_items, + clippy::unnecessary_wraps, + clippy::needless_question_mark +)] extern crate proc_macros; use proc_macros::{external, inline_macros}; diff --git a/tests/ui/try_err.stderr b/tests/ui/try_err.stderr index 4ad0e2e56a4d..80d308925246 100644 --- a/tests/ui/try_err.stderr +++ b/tests/ui/try_err.stderr @@ -1,5 +1,5 @@ error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:19:9 + --> $DIR/try_err.rs:23:9 | LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err)` @@ -11,25 +11,25 @@ LL | #![deny(clippy::try_err)] | ^^^^^^^^^^^^^^^ error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:29:9 + --> $DIR/try_err.rs:33:9 | LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:49:17 + --> $DIR/try_err.rs:53:17 | LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err)` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:68:17 + --> $DIR/try_err.rs:72:17 | LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:88:23 + --> $DIR/try_err.rs:92:23 | LL | Err(_) => Err(1)?, | ^^^^^^^ help: try this: `return Err(1)` @@ -37,7 +37,7 @@ LL | Err(_) => Err(1)?, = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:95:23 + --> $DIR/try_err.rs:99:23 | LL | Err(_) => Err(inline!(1))?, | ^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(1))` @@ -45,31 +45,31 @@ LL | Err(_) => Err(inline!(1))?, = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:122:9 + --> $DIR/try_err.rs:126:9 | LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:129:9 + --> $DIR/try_err.rs:133:9 | LL | Err(io::ErrorKind::WriteZero)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:131:9 + --> $DIR/try_err.rs:135:9 | LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:139:9 + --> $DIR/try_err.rs:143:9 | LL | Err(io::ErrorKind::NotFound)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:148:16 + --> $DIR/try_err.rs:152:16 | LL | return Err(42)?; | ^^^^^^^^ help: try this: `Err(42)`