rust-lang / rust-lang/rust-clippy
`clippy::iter_without_into_iter` suggestion does not compile
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Summary
The suggested implementation of IntoIterator does not compile.
Reproducer
I tried this code:
#![warn(clippy::all)]
#![warn(clippy::pedantic)]
pub struct Foo;
pub struct FooIter<'a>(Option<&'a Foo>);
impl<'a> Iterator for FooIter<'a> {
type Item = &'a Foo;
fn next(&mut self) -> Option<Self::Item> {
self.0.take()
}
}
impl Foo {
#[must_use]
pub fn iter(&self) -> FooIter<'_> {
FooIter(Some(self))
}
}
fn main() {
println!("Hello, world!");
}
I expected to see this happen: clippy emits a clippy::iter_without_into_iter and gives a suggested fix that compiles.
Instead, this happened:
Checking playground v0.0.1 (/playground)
warning: `iter` method without an `IntoIterator` impl for `&Foo`
--> src/main.rs:18:5
|
18 | / pub fn iter(&self) -> FooIter<'_> {
19 | | FooIter(Some(self))
20 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#iter_without_into_iter
note: the lint level is defined here
--> src/main.rs:2:9
|
2 | #![warn(clippy::pedantic)]
| ^^^^^^^^^^^^^^^^
= note: `#[warn(clippy::iter_without_into_iter)]` implied by `#[warn(clippy::pedantic)]`
help: consider implementing `IntoIterator` for `&Foo`
|
16 +
17 + impl IntoIterator for &Foo {
18 + type IntoIter = FooIter<'_>;
19 + type Iter = &Foo;
20 + fn into_iter() -> Self::IntoIter {
21 + self.iter()
22 + }
23 + }
|
warning: `playground` (bin "playground") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 0.27s
Adding the suggestion results in this code:
#![warn(clippy::all)]
#![warn(clippy::pedantic)]
pub struct Foo;
pub struct FooIter<'a>(Option<&'a Foo>);
impl<'a> Iterator for FooIter<'a> {
type Item = &'a Foo;
fn next(&mut self) -> Option<Self::Item> {
self.0.take()
}
}
impl IntoIterator for &Foo {
type IntoIter = FooIter<'_>;
type Iter = &Foo;
fn into_iter() -> Self::IntoIter {
self.iter()
}
}
impl Foo {
#[must_use]
pub fn iter(&self) -> FooIter<'_> {
FooIter(Some(self))
}
}
fn main() {
println!("Hello, world!");
}
And these compilation errors:
Compiling playground v0.0.1 (/playground)
error[E0637]: `'_` cannot be used here
--> src/main.rs:17:29
|
17 | type IntoIter = FooIter<'_>;
| ^^ `'_` is a reserved lifetime name
error[E0437]: type `Iter` is not a member of trait `IntoIterator`
--> src/main.rs:18:5
|
18 | type Iter = &Foo;
| ^^^^^----^^^^^^^^
| | |
| | help: there is an associated type with a similar name: `Item`
| not a member of trait `IntoIterator`
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/main.rs:18:17
|
18 | type Iter = &Foo;
| ^ explicit lifetime name needed here
error[E0424]: expected value, found module `self`
--> src/main.rs:20:9
|
19 | fn into_iter() -> Self::IntoIter {
| --------- this function doesn't have a `self` parameter
20 | self.iter()
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
help: add a `self` receiver parameter to make the associated `fn` a method
|
19 | fn into_iter(&self) -> Self::IntoIter {
| +++++
error[E0186]: method `into_iter` has a `self` declaration in the trait, but not in the impl
--> src/main.rs:19:5
|
19 | fn into_iter() -> Self::IntoIter {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `self` in impl
|
= note: `into_iter` from trait: `fn(Self) -> <Self as IntoIterator>::IntoIter`
error[E0046]: not all trait items implemented, missing: `Item`
--> src/main.rs:16:1
|
16 | impl IntoIterator for &Foo {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
|
= help: implement the missing item: `type Item = /* Type */;`
Some errors have detailed explanations: E0046, E0186, E0424, E0437, E0637.
For more information about an error, try `rustc --explain E0046`.
error: could not compile `playground` (bin "playground") due to 6 previous errors
The suggested code is:
- missing a lifetime generic on the impl
- uses an anonymous lifetime in an impermissible location
- missing a named lifetime on the
type Itemmember - missing the
selfparameter infn into_iter - defining an
Iterassociated type that is not present on theIntoIteratortrait - missing an
Itemassociated type
Version
Stable channel
Build using the Stable version: 1.73.0
clippy 0.1.75 (2023-10-19 4578435)
from the playground
Additional Labels
@rustbot label +I-suggestion-causes-error
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue with the Rust code and compiler output in the report, then trace the iter_without_into_iter lint's suggestion generation. Done means the emitted IntoIterator implementation is valid Rust and the reported reproducer compiles with the suggestion applied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100