| //@no-rustfix |
| #![warn(clippy::into_iter_without_iter)] |
| |
| use std::iter::IntoIterator; |
| |
| pub struct S1; |
| impl<'a> IntoIterator for &'a S1 { |
| //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method |
| type IntoIter = std::slice::Iter<'a, u8>; |
| type Item = &'a u8; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| impl<'a> IntoIterator for &'a mut S1 { |
| //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method |
| type IntoIter = std::slice::IterMut<'a, u8>; |
| type Item = &'a mut u8; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| pub struct S2<T>(T); |
| impl<'a, T> IntoIterator for &'a S2<T> { |
| //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method |
| type IntoIter = std::slice::Iter<'a, T>; |
| type Item = &'a T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| impl<'a, T> IntoIterator for &'a mut S2<T> { |
| //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method |
| type IntoIter = std::slice::IterMut<'a, T>; |
| type Item = &'a mut T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| // Both iter and iter_mut methods exist, don't lint |
| pub struct S3<'a, T>(&'a T); |
| impl<'a, T> S3<'a, T> { |
| fn iter(&self) -> std::slice::Iter<'a, T> { |
| todo!() |
| } |
| fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { |
| todo!() |
| } |
| } |
| impl<'a, T> IntoIterator for &S3<'a, T> { |
| type IntoIter = std::slice::Iter<'a, T>; |
| type Item = &'a T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| impl<'a, T> IntoIterator for &mut S3<'a, T> { |
| type IntoIter = std::slice::IterMut<'a, T>; |
| type Item = &'a mut T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| // Only `iter` exists, no `iter_mut` |
| pub struct S4<'a, T>(&'a T); |
| |
| impl<'a, T> S4<'a, T> { |
| fn iter(&self) -> std::slice::Iter<'a, T> { |
| todo!() |
| } |
| } |
| |
| impl<'a, T> IntoIterator for &S4<'a, T> { |
| type IntoIter = std::slice::Iter<'a, T>; |
| type Item = &'a T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| impl<'a, T> IntoIterator for &mut S4<'a, T> { |
| //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method |
| type IntoIter = std::slice::IterMut<'a, T>; |
| type Item = &'a mut T; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| // `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize" |
| // aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead |
| // to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias). |
| pub struct S5; |
| |
| impl S5 { |
| fn iter(&self) -> std::slice::Iter<'static, u8> { |
| todo!() |
| } |
| } |
| |
| pub type Alias = S5; |
| |
| impl IntoIterator for &Alias { |
| type IntoIter = std::slice::Iter<'static, u8>; |
| type Item = &'static u8; |
| fn into_iter(self) -> Self::IntoIter { |
| todo!() |
| } |
| } |
| |
| fn main() {} |
| |
| pub mod issue11635 { |
| // A little more involved than the original repro in the issue, but this tests that it correctly |
| // works for more than one deref step |
| |
| use std::ops::Deref; |
| |
| pub struct Thing(Vec<u8>); |
| pub struct Thing2(Thing); |
| |
| impl Deref for Thing { |
| type Target = [u8]; |
| |
| fn deref(&self) -> &Self::Target { |
| &self.0 |
| } |
| } |
| |
| impl Deref for Thing2 { |
| type Target = Thing; |
| fn deref(&self) -> &Self::Target { |
| &self.0 |
| } |
| } |
| |
| impl<'a> IntoIterator for &'a Thing2 { |
| type Item = &'a u8; |
| type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; |
| |
| fn into_iter(self) -> Self::IntoIter { |
| self.0.iter() |
| } |
| } |
| } |