rust-clippy
rust-clippy copied to clipboard
`iter_on_empty_collections` emitted when `iter::empty()` cannot work
Summary
The suggestion for iter_on_empty_collections
causes an incompatible match arm error in some cases.
Lint Name
iter_on_empty_collections
Reproducer
I am having a hard time finding a minimal reproduction, this seems to work OK in most other cases I try. Probably clippy just having trouble seeing through the mess of iterators. This is a snip from the full example:
use itertools::Either;
impl Source {
/// Iterate through all morph info available
pub fn morphs(&self) -> impl Iterator<Item = &MorphInfo> {
match self {
Source::Affix(rule) => {
let iter = rule
.patterns()
.iter()
.flat_map(|pat| pat.morph_info().iter());
Either::Left(iter)
}
// v is `&Box<[Arc<MorphInfo>]>`
Source::Dict(v) => Either::Right(v.as_ref().iter()),
Source::Personal(v) => Either::Right(v.morph.iter()),
// problem arm
Source::Raw => Either::Right([].iter()),
}
.map(AsRef::as_ref)
}
}
I saw this happen:
warning: `iter` call on an empty collection
--> zspell/src/dict/types.rs:77:42
|
77 | Source::Raw => Either::Right([].iter()),
| ^^^^^^^^^ help: try: `std::iter::empty()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections
note: the lint level is defined here
--> zspell/src/lib.rs:87:9
|
87 | #![warn(clippy::nursery)]
| ^^^^^^^^^^^^^^^
= note: `#[warn(clippy::iter_on_empty_collections)]` implied by `#[warn(clippy::nursery)]`
Following the lint gives
error[E0308]: `match` arms have incompatible types
--> zspell/src/dict/types.rs:77:28
|
67 | / match self {
68 | | Source::Affix(rule) => {
69 | | let iter = rule
70 | | .patterns()
71 | | .iter()
72 | | .flat_map(|pat| pat.morph_info().iter());
| | ----- the expected closure
73 | | Either::Left(iter)
| | ------------------ this is found to be of type `itertools::Either<std::iter::FlatMap<std::slice::Iter<'_, dict::rule::AfxRulePattern>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>, [closure@zspell/src/dict/types.rs:72:31: 72:36]>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>>`
74 | | }
75 | | Source::Dict(v) => Either::Right(v.as_ref().iter()),
| | -------------------------------- this is found to be of type `itertools::Either<std::iter::FlatMap<std::slice::Iter<'_, dict::rule::AfxRulePattern>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>, [closure@zspell/src/dict/types.rs:72:31: 72:36]>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>>`
76 | | Source::Personal(v) => Either::Right(v.morph.iter()),
| | ----------------------------- this is found to be of type `itertools::Either<std::iter::FlatMap<std::slice::Iter<'_, dict::rule::AfxRulePattern>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>, [closure@zspell/src/dict/types.rs:72:31: 72:36]>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>>`
77 | | Source::Raw => Either::Right(std::iter::empty()),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Either<FlatMap<Iter<'_, ...>, ..., ...>, ...>`, found `Either<_, Empty<_>>`
78 | | }
| |_________- `match` arms have incompatible types
|
= note: expected enum `itertools::Either<std::iter::FlatMap<std::slice::Iter<'_, dict::rule::AfxRulePattern>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>, [closure@zspell/src/dict/types.rs:72:31: 72:36]>, std::slice::Iter<'_, std::sync::Arc<morph::MorphInfo>>>`
found enum `itertools::Either<_, std::iter::Empty<_>>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `zspell` (lib) due to previous error
I expected to see this happen: no error
Version
rustc 1.74.0-nightly (b4e54c6e3 2023-09-11)
binary: rustc
commit-hash: b4e54c6e39984840a04dcd02d14ec8c3574d30e5
commit-date: 2023-09-11
host: x86_64-unknown-linux-gnu
release: 1.74.0-nightly
LLVM version: 17.0.0
Additional Labels
@rustbot label +I-suggestion-causes-error
@rustbot claim