[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect
[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count
-[`iter_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_empty
[`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop
[`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_slice
[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_not_returning_iterator
[`iter_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth
[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero
-[`iter_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_once
+[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections
+[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items
[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned
[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
[`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain
methods::ITERATOR_STEP_BY_ZERO,
methods::ITER_CLONED_COLLECT,
methods::ITER_COUNT,
- methods::ITER_EMPTY,
methods::ITER_NEXT_SLICE,
methods::ITER_NTH,
methods::ITER_NTH_ZERO,
- methods::ITER_ONCE,
+ methods::ITER_ON_EMPTY_COLLECTIONS,
+ methods::ITER_ON_SINGLE_ITEMS,
methods::ITER_OVEREAGER_CLONED,
methods::ITER_SKIP_NEXT,
methods::ITER_WITH_DRAIN,
LintId::of(index_refutable_slice::INDEX_REFUTABLE_SLICE),
LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE),
- LintId::of(methods::ITER_EMPTY),
- LintId::of(methods::ITER_ONCE),
+ LintId::of(methods::ITER_ON_EMPTY_COLLECTIONS),
+ LintId::of(methods::ITER_ON_SINGLE_ITEMS),
LintId::of(methods::ITER_WITH_DRAIN),
LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
--- /dev/null
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet;
+use clippy_utils::{get_expr_use_or_unification_node, is_lang_ctor, is_no_std_crate};
+
+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<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
+ let item = match &recv.kind {
+ ExprKind::Array(v) if v.len() <= 1 => v.first(),
+ ExprKind::Path(p) => {
+ if is_lang_ctor(cx, p, OptionNone) {
+ None
+ } else {
+ return;
+ }
+ },
+ ExprKind::Call(f, some_args) if some_args.len() == 1 => {
+ if let ExprKind::Path(p) = &f.kind {
+ if is_lang_ctor(cx, p, OptionSome) {
+ Some(&some_args[0])
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ },
+ _ => 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,
+ );
+ }
+}
+++ /dev/null
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
-use clippy_utils::{get_expr_use_or_unification_node, is_lang_ctor, is_no_std_crate};
-
-use rustc_errors::Applicability;
-use rustc_hir::LangItem::{OptionNone, OptionSome};
-use rustc_hir::{Expr, ExprKind, Node};
-use rustc_lint::LateContext;
-
-use super::{ITER_EMPTY, ITER_ONCE};
-
-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<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
- let item = match &recv.kind {
- ExprKind::Array(v) if v.len() <= 1 => v.first(),
- ExprKind::Path(p) => {
- if is_lang_ctor(cx, p, OptionNone) {
- None
- } else {
- return;
- }
- },
- ExprKind::Call(f, some_args) if some_args.len() == 1 => {
- if let ExprKind::Path(p) = &f.kind {
- if is_lang_ctor(cx, p, OptionSome) {
- Some(&some_args[0])
- } else {
- return;
- }
- } else {
- return;
- }
- },
- _ => 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_ONCE,
- expr.span,
- &format!("`{method_name}` call on a collection with only one item"),
- "try",
- sugg,
- Applicability::MaybeIncorrect,
- );
- } else {
- span_lint_and_sugg(
- cx,
- ITER_EMPTY,
- 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,
- );
- }
-}
mod iter_next_slice;
mod iter_nth;
mod iter_nth_zero;
-mod iter_once_empty;
+mod iter_on_single_or_empty_collections;
mod iter_overeager_cloned;
mod iter_skip_next;
mod iter_with_drain;
///
/// The type of the resulting iterator might become incompatible with its usage
#[clippy::version = "1.64.0"]
- pub ITER_ONCE,
+ pub ITER_ON_SINGLE_ITEMS,
nursery,
"Iterator for array of length 1"
}
///
/// The type of the resulting iterator might become incompatible with its usage
#[clippy::version = "1.64.0"]
- pub ITER_EMPTY,
+ pub ITER_ON_EMPTY_COLLECTIONS,
nursery,
"Iterator for empty array"
}
NEEDLESS_OPTION_TAKE,
NO_EFFECT_REPLACE,
OBFUSCATED_IF_ELSE,
- ITER_ONCE,
- ITER_EMPTY
+ ITER_ON_SINGLE_ITEMS,
+ ITER_ON_EMPTY_COLLECTIONS
]);
/// Extracts a method call name, args, and `Span` of the method name.
("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_once_empty::check(cx, expr, name, recv),
+ ("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);
+++ /dev/null
-// run-rustfix
-#![warn(clippy::iter_empty)]
-#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
-
-fn array() {
- assert_eq!(std::iter::empty().next(), Option::<i32>::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::<i32>::None);
- assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);
- assert_eq!(std::iter::empty().next(), Option::<&i32>::None);
-
- // Don't trigger on non-iter methods
- let _: Option<String> = None.clone();
- let _: [String; 0] = [].clone();
-
- // Don't trigger on match or if branches
- let _ = match 123 {
- 123 => [].iter(),
- _ => ["test"].iter(),
- };
-
- let _ = if false { ["test"].iter() } else { [].iter() };
-}
-
-macro_rules! in_macros {
- () => {
- assert_eq!([].into_iter().next(), Option::<i32>::None);
- assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!([].iter().next(), Option::<&i32>::None);
- assert_eq!(None.into_iter().next(), Option::<i32>::None);
- assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!(None.iter().next(), Option::<&i32>::None);
- };
-}
-
-// Don't trigger on a `None` that isn't std's option
-mod custom_option {
- #[allow(unused)]
- enum CustomOption {
- Some(i32),
- None,
- }
-
- impl CustomOption {
- fn iter(&self) {}
- fn iter_mut(&mut self) {}
- fn into_iter(self) {}
- }
- use CustomOption::*;
-
- pub fn custom_option() {
- None.iter();
- None.iter_mut();
- None.into_iter();
- }
-}
-
-fn main() {
- array();
- custom_option::custom_option();
- in_macros!();
-}
+++ /dev/null
-// run-rustfix
-#![warn(clippy::iter_empty)]
-#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
-
-fn array() {
- assert_eq!([].into_iter().next(), Option::<i32>::None);
- assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!([].iter().next(), Option::<&i32>::None);
- assert_eq!(None.into_iter().next(), Option::<i32>::None);
- assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!(None.iter().next(), Option::<&i32>::None);
-
- // Don't trigger on non-iter methods
- let _: Option<String> = None.clone();
- let _: [String; 0] = [].clone();
-
- // Don't trigger on match or if branches
- let _ = match 123 {
- 123 => [].iter(),
- _ => ["test"].iter(),
- };
-
- let _ = if false { ["test"].iter() } else { [].iter() };
-}
-
-macro_rules! in_macros {
- () => {
- assert_eq!([].into_iter().next(), Option::<i32>::None);
- assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!([].iter().next(), Option::<&i32>::None);
- assert_eq!(None.into_iter().next(), Option::<i32>::None);
- assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
- assert_eq!(None.iter().next(), Option::<&i32>::None);
- };
-}
-
-// Don't trigger on a `None` that isn't std's option
-mod custom_option {
- #[allow(unused)]
- enum CustomOption {
- Some(i32),
- None,
- }
-
- impl CustomOption {
- fn iter(&self) {}
- fn iter_mut(&mut self) {}
- fn into_iter(self) {}
- }
- use CustomOption::*;
-
- pub fn custom_option() {
- None.iter();
- None.iter_mut();
- None.into_iter();
- }
-}
-
-fn main() {
- array();
- custom_option::custom_option();
- in_macros!();
-}
+++ /dev/null
-error: `into_iter` call on an empty collection
- --> $DIR/iter_empty.rs:6:16
- |
-LL | assert_eq!([].into_iter().next(), Option::<i32>::None);
- | ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
- |
- = note: `-D clippy::iter-empty` implied by `-D warnings`
-
-error: `iter_mut` call on an empty collection
- --> $DIR/iter_empty.rs:7:16
- |
-LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
- | ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
-
-error: `iter` call on an empty collection
- --> $DIR/iter_empty.rs:8:16
- |
-LL | assert_eq!([].iter().next(), Option::<&i32>::None);
- | ^^^^^^^^^ help: try: `std::iter::empty()`
-
-error: `into_iter` call on an empty collection
- --> $DIR/iter_empty.rs:9:16
- |
-LL | assert_eq!(None.into_iter().next(), Option::<i32>::None);
- | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
-
-error: `iter_mut` call on an empty collection
- --> $DIR/iter_empty.rs:10:16
- |
-LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
- | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
-
-error: `iter` call on an empty collection
- --> $DIR/iter_empty.rs:11:16
- |
-LL | assert_eq!(None.iter().next(), Option::<&i32>::None);
- | ^^^^^^^^^^^ help: try: `std::iter::empty()`
-
-error: aborting due to 6 previous errors
-
--- /dev/null
+// run-rustfix
+#![warn(clippy::iter_on_empty_collections)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!(std::iter::empty().next(), Option::<i32>::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::<i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);
+ assert_eq!(std::iter::empty().next(), Option::<&i32>::None);
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = None.clone();
+ let _: [String; 0] = [].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+ };
+}
+
+// Don't trigger on a `None` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ None.iter();
+ None.iter_mut();
+ None.into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
--- /dev/null
+// run-rustfix
+#![warn(clippy::iter_on_empty_collections)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = None.clone();
+ let _: [String; 0] = [].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].iter(),
+ };
+
+ let _ = if false { ["test"].iter() } else { [].iter() };
+}
+
+macro_rules! in_macros {
+ () => {
+ assert_eq!([].into_iter().next(), Option::<i32>::None);
+ assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!([].iter().next(), Option::<&i32>::None);
+ assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ assert_eq!(None.iter().next(), Option::<&i32>::None);
+ };
+}
+
+// Don't trigger on a `None` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ None.iter();
+ None.iter_mut();
+ None.into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
--- /dev/null
+error: `into_iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:6:16
+ |
+LL | assert_eq!([].into_iter().next(), Option::<i32>::None);
+ | ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+ |
+ = note: `-D clippy::iter-on-empty-collections` implied by `-D warnings`
+
+error: `iter_mut` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:7:16
+ |
+LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
+ | ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:8:16
+ |
+LL | assert_eq!([].iter().next(), Option::<&i32>::None);
+ | ^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `into_iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:9:16
+ |
+LL | assert_eq!(None.into_iter().next(), Option::<i32>::None);
+ | ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter_mut` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:10:16
+ |
+LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
+ | ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: `iter` call on an empty collection
+ --> $DIR/iter_on_empty_collections.rs:11:16
+ |
+LL | assert_eq!(None.iter().next(), Option::<&i32>::None);
+ | ^^^^^^^^^^^ help: try: `std::iter::empty()`
+
+error: aborting due to 6 previous errors
+
--- /dev/null
+// run-rustfix
+#![warn(clippy::iter_on_single_items)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ 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));
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = Some("test".to_string()).clone();
+ let _: [String; 1] = ["test".to_string()].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].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));
+ };
+}
+
+// Don't trigger on a `Some` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ Some(3).iter();
+ Some(3).iter_mut();
+ Some(3).into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
--- /dev/null
+// run-rustfix
+#![warn(clippy::iter_on_single_items)]
+#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
+
+fn array() {
+ 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));
+
+ // Don't trigger on non-iter methods
+ let _: Option<String> = Some("test".to_string()).clone();
+ let _: [String; 1] = ["test".to_string()].clone();
+
+ // Don't trigger on match or if branches
+ let _ = match 123 {
+ 123 => [].iter(),
+ _ => ["test"].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));
+ };
+}
+
+// Don't trigger on a `Some` that isn't std's option
+mod custom_option {
+ #[allow(unused)]
+ enum CustomOption {
+ Some(i32),
+ None,
+ }
+
+ impl CustomOption {
+ fn iter(&self) {}
+ fn iter_mut(&mut self) {}
+ fn into_iter(self) {}
+ }
+ use CustomOption::*;
+
+ pub fn custom_option() {
+ Some(3).iter();
+ Some(3).iter_mut();
+ Some(3).into_iter();
+ }
+}
+
+fn main() {
+ array();
+ custom_option::custom_option();
+ in_macros!();
+}
--- /dev/null
+error: `into_iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:6:16
+ |
+LL | assert_eq!([123].into_iter().next(), Some(123));
+ | ^^^^^^^^^^^^^^^^^ help: try: `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
+ --> $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)`
+
+error: `iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:8:16
+ |
+LL | assert_eq!([123].iter().next(), Some(&123));
+ | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
+
+error: `into_iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:9:16
+ |
+LL | assert_eq!(Some(123).into_iter().next(), Some(123));
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
+
+error: `iter_mut` call on a collection with only one item
+ --> $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)`
+
+error: `iter` call on a collection with only one item
+ --> $DIR/iter_on_single_items.rs:11:16
+ |
+LL | assert_eq!(Some(123).iter().next(), Some(&123));
+ | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
+
+error: aborting due to 6 previous errors
+
+++ /dev/null
-// run-rustfix
-#![warn(clippy::iter_once)]
-#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
-
-fn array() {
- 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));
-
- // Don't trigger on non-iter methods
- let _: Option<String> = Some("test".to_string()).clone();
- let _: [String; 1] = ["test".to_string()].clone();
-
- // Don't trigger on match or if branches
- let _ = match 123 {
- 123 => [].iter(),
- _ => ["test"].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));
- };
-}
-
-// Don't trigger on a `Some` that isn't std's option
-mod custom_option {
- #[allow(unused)]
- enum CustomOption {
- Some(i32),
- None,
- }
-
- impl CustomOption {
- fn iter(&self) {}
- fn iter_mut(&mut self) {}
- fn into_iter(self) {}
- }
- use CustomOption::*;
-
- pub fn custom_option() {
- Some(3).iter();
- Some(3).iter_mut();
- Some(3).into_iter();
- }
-}
-
-fn main() {
- array();
- custom_option::custom_option();
- in_macros!();
-}
+++ /dev/null
-// run-rustfix
-#![warn(clippy::iter_once)]
-#![allow(clippy::iter_next_slice, clippy::redundant_clone)]
-
-fn array() {
- 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));
-
- // Don't trigger on non-iter methods
- let _: Option<String> = Some("test".to_string()).clone();
- let _: [String; 1] = ["test".to_string()].clone();
-
- // Don't trigger on match or if branches
- let _ = match 123 {
- 123 => [].iter(),
- _ => ["test"].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));
- };
-}
-
-// Don't trigger on a `Some` that isn't std's option
-mod custom_option {
- #[allow(unused)]
- enum CustomOption {
- Some(i32),
- None,
- }
-
- impl CustomOption {
- fn iter(&self) {}
- fn iter_mut(&mut self) {}
- fn into_iter(self) {}
- }
- use CustomOption::*;
-
- pub fn custom_option() {
- Some(3).iter();
- Some(3).iter_mut();
- Some(3).into_iter();
- }
-}
-
-fn main() {
- array();
- custom_option::custom_option();
- in_macros!();
-}
+++ /dev/null
-error: `into_iter` call on a collection with only one item
- --> $DIR/iter_once.rs:6:16
- |
-LL | assert_eq!([123].into_iter().next(), Some(123));
- | ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
- |
- = note: `-D clippy::iter-once` implied by `-D warnings`
-
-error: `iter_mut` call on a collection with only one item
- --> $DIR/iter_once.rs:7:16
- |
-LL | assert_eq!([123].iter_mut().next(), Some(&mut 123));
- | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
-
-error: `iter` call on a collection with only one item
- --> $DIR/iter_once.rs:8:16
- |
-LL | assert_eq!([123].iter().next(), Some(&123));
- | ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
-
-error: `into_iter` call on a collection with only one item
- --> $DIR/iter_once.rs:9:16
- |
-LL | assert_eq!(Some(123).into_iter().next(), Some(123));
- | ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
-
-error: `iter_mut` call on a collection with only one item
- --> $DIR/iter_once.rs:10:16
- |
-LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
- | ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
-
-error: `iter` call on a collection with only one item
- --> $DIR/iter_once.rs:11:16
- |
-LL | assert_eq!(Some(123).iter().next(), Some(&123));
- | ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
-
-error: aborting due to 6 previous errors
-