diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 88042525c4f75..4b39f1d9f47fe 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -19,6 +19,11 @@ declare_clippy_lint! { /// It's not bad, but having them is idiomatic and allows the type to be used in for loops directly /// (`for val in &iter {}`), without having to first call `iter()` or `iter_mut()`. /// + /// ### Limitations + /// This lint focuses on providing an idiomatic API. Therefore, it will only + /// lint on types which are accessible outside of the crate. For internal types, + /// the `IntoIterator` trait can be implemented on demand if it is actually needed. + /// /// ### Example /// ```no_run /// struct MySlice<'a>(&'a [u8]); @@ -61,6 +66,14 @@ declare_clippy_lint! { /// by just calling `.iter()`, instead of the more awkward `<&Type>::into_iter` or `(&val).into_iter()` syntax /// in case of ambiguity with another `IntoIterator` impl. /// + /// ### Limitations + /// This lint focuses on providing an idiomatic API. Therefore, it will only + /// lint on types which are accessible outside of the crate. For internal types, + /// these methods can be added on demand if they are actually needed. Otherwise, + /// it would trigger the [`dead_code`] lint for the unused method. + /// + /// [`dead_code`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code + /// /// ### Example /// ```no_run /// struct MySlice<'a>(&'a [u8]); @@ -104,6 +117,12 @@ fn is_nameable_in_impl_trait(ty: &rustc_hir::Ty<'_>) -> bool { !matches!(ty.kind, TyKind::OpaqueDef(..)) } +fn is_ty_exported(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { + ty.ty_adt_def() + .and_then(|adt| adt.did().as_local()) + .is_some_and(|did| cx.effective_visibilities.is_exported(did)) +} + /// Returns the deref chain of a type, starting with the type itself. fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iterator> + 'cx { iter::successors(Some(ty), |&ty| { @@ -154,6 +173,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { None } }) + && is_ty_exported(cx, ty) { span_lint_and_then( cx, @@ -226,6 +246,7 @@ impl {self_ty_without_ref} {{ ) // Only lint if the `IntoIterator` impl doesn't actually exist && !implements_trait(cx, ref_ty, into_iter_did, &[]) + && is_ty_exported(cx, ref_ty.peel_refs()) { let self_ty_snippet = format!("{borrow_prefix}{}", snippet(cx, imp.self_ty.span, "..")); @@ -247,8 +268,8 @@ impl {self_ty_without_ref} {{ " impl IntoIterator for {self_ty_snippet} {{ type IntoIter = {ret_ty}; - type Iter = {iter_ty}; - fn into_iter() -> Self::IntoIter {{ + type Item = {iter_ty}; + fn into_iter(self) -> Self::IntoIter {{ self.iter() }} }} diff --git a/tests/ui/into_iter_without_iter.rs b/tests/ui/into_iter_without_iter.rs index e6ff821a8ad04..448d0114dff82 100644 --- a/tests/ui/into_iter_without_iter.rs +++ b/tests/ui/into_iter_without_iter.rs @@ -3,127 +3,117 @@ use std::iter::IntoIterator; -fn main() { - { - struct S; - - impl<'a> IntoIterator for &'a S { - //~^ 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 S { - //~^ 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 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!() } - { - struct S(T); - impl<'a, T> IntoIterator for &'a S { - //~^ 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 S { - //~^ 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!() - } - } +} +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!() } - { - // Both iter and iter_mut methods exist, don't lint - struct S<'a, T>(&'a T); - - impl<'a, T> S<'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 &S<'a, T> { - type IntoIter = std::slice::Iter<'a, T>; - type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +pub struct S2(T); +impl<'a, T> IntoIterator for &'a S2 { + //~^ 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 { + //~^ 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!() + } +} - impl<'a, T> IntoIterator for &mut S<'a, T> { - 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` - struct S<'a, T>(&'a T); +} - impl<'a, T> S<'a, T> { - fn iter(&self) -> std::slice::Iter<'a, T> { - todo!() - } - } +// Only `iter` exists, no `iter_mut` +pub struct S4<'a, T>(&'a T); - impl<'a, T> IntoIterator for &S<'a, T> { - type IntoIter = std::slice::Iter<'a, T>; - type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +impl<'a, T> S4<'a, T> { + fn iter(&self) -> std::slice::Iter<'a, T> { + todo!() + } +} - impl<'a, T> IntoIterator for &mut S<'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!() - } - } +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!() } - { - // `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). - struct S; +} - impl S { - fn iter(&self) -> std::slice::Iter<'static, u8> { - 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!() + } +} - type Alias = S; +// `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 IntoIterator for &Alias { - type IntoIter = std::slice::Iter<'static, u8>; - type Item = &'static u8; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +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 issue11635() { +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 diff --git a/tests/ui/into_iter_without_iter.stderr b/tests/ui/into_iter_without_iter.stderr index f543d1d8e86c1..70f3f82a936c6 100644 --- a/tests/ui/into_iter_without_iter.stderr +++ b/tests/ui/into_iter_without_iter.stderr @@ -1,21 +1,21 @@ error: `IntoIterator` implemented for a reference type without an `iter` method - --> $DIR/into_iter_without_iter.rs:10:9 + --> $DIR/into_iter_without_iter.rs:7:1 | -LL | / impl<'a> IntoIterator for &'a S { +LL | / impl<'a> IntoIterator for &'a S1 { LL | | -LL | | type IntoIter = std::slice::Iter<'a, u8>; -LL | | type Item = &'a u8; +LL | | type IntoIter = std::slice::Iter<'a, u8>; +LL | | type Item = &'a u8; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | = note: `-D clippy::into-iter-without-iter` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]` help: consider implementing `iter` | -LL ~ -LL + impl S { +LL + +LL + impl S1 { LL + fn iter(&self) -> std::slice::Iter<'a, u8> { LL + <&Self as IntoIterator>::into_iter(self) LL + } @@ -23,21 +23,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:18:9 + --> $DIR/into_iter_without_iter.rs:15:1 | -LL | / impl<'a> IntoIterator for &'a mut S { +LL | / impl<'a> IntoIterator for &'a mut S1 { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, u8>; -LL | | type Item = &'a mut u8; +LL | | type IntoIter = std::slice::IterMut<'a, u8>; +LL | | type Item = &'a mut u8; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S { +LL + +LL + impl S1 { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } @@ -45,21 +45,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter` method - --> $DIR/into_iter_without_iter.rs:29:9 + --> $DIR/into_iter_without_iter.rs:25:1 | -LL | / impl<'a, T> IntoIterator for &'a S { +LL | / impl<'a, T> IntoIterator for &'a S2 { LL | | -LL | | type IntoIter = std::slice::Iter<'a, T>; -LL | | type Item = &'a T; +LL | | type IntoIter = std::slice::Iter<'a, T>; +LL | | type Item = &'a T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter` | -LL ~ -LL + impl S { +LL + +LL + impl S2 { LL + fn iter(&self) -> std::slice::Iter<'a, T> { LL + <&Self as IntoIterator>::into_iter(self) LL + } @@ -67,21 +67,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:37:9 + --> $DIR/into_iter_without_iter.rs:33:1 | -LL | / impl<'a, T> IntoIterator for &'a mut S { +LL | / impl<'a, T> IntoIterator for &'a mut S2 { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, T>; -LL | | type Item = &'a mut T; +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S { +LL + +LL + impl S2 { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } @@ -89,21 +89,21 @@ LL + } | error: `IntoIterator` implemented for a reference type without an `iter_mut` method - --> $DIR/into_iter_without_iter.rs:93:9 + --> $DIR/into_iter_without_iter.rs:84:1 | -LL | / impl<'a, T> IntoIterator for &mut S<'a, T> { +LL | / impl<'a, T> IntoIterator for &mut S4<'a, T> { LL | | -LL | | type IntoIter = std::slice::IterMut<'a, T>; -LL | | type Item = &'a mut T; +LL | | type IntoIter = std::slice::IterMut<'a, T>; +LL | | type Item = &'a mut T; ... | -LL | | } -LL | | } - | |_________^ +LL | | } +LL | | } + | |_^ | help: consider implementing `iter_mut` | -LL ~ -LL + impl S<'a, T> { +LL + +LL + impl S4<'a, T> { LL + fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> { LL + <&mut Self as IntoIterator>::into_iter(self) LL + } diff --git a/tests/ui/iter_without_into_iter.rs b/tests/ui/iter_without_into_iter.rs index cedb756c79de1..29f526b455cb9 100644 --- a/tests/ui/iter_without_into_iter.rs +++ b/tests/ui/iter_without_into_iter.rs @@ -1,120 +1,124 @@ //@no-rustfix #![warn(clippy::iter_without_into_iter)] -fn main() { - { - struct S; - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - [].iter() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - [].iter_mut() - } - } - } - { - struct S; - impl S { - pub fn iter(&self) -> impl Iterator { - // RPITIT is not stable, so we can't generally suggest it here yet - [].iter() - } - } - } - { - struct S<'a>(&'a mut [u8]); - impl<'a> S<'a> { - pub fn iter(&self) -> std::slice::Iter<'_, u8> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - self.0.iter() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - self.0.iter_mut() - } - } - } - { - // Incompatible signatures - struct S; - impl S { - pub fn iter(self) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S2; - impl S2 { - pub async fn iter(&self) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S3; - impl S3 { - pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> { - todo!() - } - } - struct S4(T); - impl S4 { - pub fn iter(&self) -> std::slice::Iter<'static, (T, U)> { - todo!() - } - } - struct S5(T); - impl S5 { - pub fn iter(&self) -> std::slice::Iter<'static, T> { - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, T> { - //~^ ERROR: `iter` method without an `IntoIterator` impl - todo!() - } - pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { - //~^ ERROR: `iter_mut` method without an `IntoIterator` impl - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter(&self) -> std::slice::Iter<'_, T> { - // Don't lint, there's an existing (wrong) IntoIterator impl - todo!() - } - } +pub struct S1; +impl S1 { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + [].iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + [].iter_mut() + } +} + +pub struct S2; +impl S2 { + pub fn iter(&self) -> impl Iterator { + // RPITIT is not stable, so we can't generally suggest it here yet + [].iter() + } +} + +pub struct S3<'a>(&'a mut [u8]); +impl<'a> S3<'a> { + pub fn iter(&self) -> std::slice::Iter<'_, u8> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + self.0.iter() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + self.0.iter_mut() + } +} + +// Incompatible signatures +pub struct S4; +impl S4 { + pub fn iter(self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S5; +impl S5 { + pub async fn iter(&self) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S6; +impl S6 { + pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> { + todo!() + } +} + +pub struct S7(T); +impl S7 { + pub fn iter(&self) -> std::slice::Iter<'static, (T, U)> { + todo!() + } +} + +pub struct S8(T); +impl S8 { + pub fn iter(&self) -> std::slice::Iter<'static, T> { + todo!() + } +} + +// =========================== +pub struct S9(T); +impl S9 { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + //~^ ERROR: `iter` method without an `IntoIterator` impl + todo!() + } + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { + //~^ ERROR: `iter_mut` method without an `IntoIterator` impl + todo!() + } +} + +pub struct S10(T); +impl S10 { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} + +impl<'a, T> IntoIterator for &'a S10 { + type Item = &'a String; + type IntoIter = std::slice::Iter<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - impl<'a, T> IntoIterator for &'a S { - type Item = &'a String; - type IntoIter = std::slice::Iter<'a, String>; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } - } - { - struct S(T); - impl S { - pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> { - // Don't lint, there's an existing (wrong) IntoIterator impl - todo!() - } - } +pub struct S11(T); +impl S11 { + pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> { + // Don't lint, there's an existing (wrong) IntoIterator impl + todo!() + } +} +impl<'a, T> IntoIterator for &'a mut S11 { + type Item = &'a mut String; + type IntoIter = std::slice::IterMut<'a, String>; + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} - impl<'a, T> IntoIterator for &'a mut S { - type Item = &'a mut String; - type IntoIter = std::slice::IterMut<'a, String>; - fn into_iter(self) -> Self::IntoIter { - todo!() - } - } +// Private type not exported: don't lint +struct S12; +impl S12 { + fn iter(&self) -> std::slice::Iter<'_, u8> { + todo!() } } + +fn main() {} diff --git a/tests/ui/iter_without_into_iter.stderr b/tests/ui/iter_without_into_iter.stderr index 9d0b99415a50e..af5afd47bfc41 100644 --- a/tests/ui/iter_without_into_iter.stderr +++ b/tests/ui/iter_without_into_iter.stderr @@ -1,146 +1,146 @@ -error: `iter` method without an `IntoIterator` impl for `&S` - --> $DIR/iter_without_into_iter.rs:8:13 +error: `iter` method without an `IntoIterator` impl for `&S1` + --> $DIR/iter_without_into_iter.rs:6:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { LL | | -LL | | [].iter() -LL | | } - | |_____________^ +LL | | [].iter() +LL | | } + | |_____^ | = note: `-D clippy::iter-without-into-iter` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]` -help: consider implementing `IntoIterator` for `&S` +help: consider implementing `IntoIterator` for `&S1` | -LL ~ -LL + impl IntoIterator for &S { +LL + +LL + impl IntoIterator for &S1 { LL + type IntoIter = std::slice::Iter<'_, u8>; -LL + type Iter = &u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S` - --> $DIR/iter_without_into_iter.rs:12:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S1` + --> $DIR/iter_without_into_iter.rs:10:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { LL | | -LL | | [].iter_mut() -LL | | } - | |_____________^ +LL | | [].iter_mut() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S` +help: consider implementing `IntoIterator` for `&mut S1` | -LL ~ -LL + impl IntoIterator for &mut S { +LL + +LL + impl IntoIterator for &mut S1 { LL + type IntoIter = std::slice::IterMut<'_, u8>; -LL + type Iter = &mut u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S<'a>` - --> $DIR/iter_without_into_iter.rs:30:13 +error: `iter` method without an `IntoIterator` impl for `&S3<'a>` + --> $DIR/iter_without_into_iter.rs:26:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, u8> { LL | | -LL | | self.0.iter() -LL | | } - | |_____________^ +LL | | self.0.iter() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S<'a>` +help: consider implementing `IntoIterator` for `&S3<'a>` | -LL ~ -LL + impl IntoIterator for &S<'a> { +LL + +LL + impl IntoIterator for &S3<'a> { LL + type IntoIter = std::slice::Iter<'_, u8>; -LL + type Iter = &u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S<'a>` - --> $DIR/iter_without_into_iter.rs:34:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>` + --> $DIR/iter_without_into_iter.rs:30:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> { LL | | -LL | | self.0.iter_mut() -LL | | } - | |_____________^ +LL | | self.0.iter_mut() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S<'a>` +help: consider implementing `IntoIterator` for `&mut S3<'a>` | -LL ~ -LL + impl IntoIterator for &mut S<'a> { +LL + +LL + impl IntoIterator for &mut S3<'a> { LL + type IntoIter = std::slice::IterMut<'_, u8>; -LL + type Iter = &mut u8; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut u8; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S5` - --> $DIR/iter_without_into_iter.rs:68:13 +error: `iter` method without an `IntoIterator` impl for `&S8` + --> $DIR/iter_without_into_iter.rs:67:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { -LL | | todo!() -LL | | } - | |_____________^ +LL | / pub fn iter(&self) -> std::slice::Iter<'static, T> { +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S5` +help: consider implementing `IntoIterator` for `&S8` | -LL ~ -LL + impl IntoIterator for &S5 { +LL + +LL + impl IntoIterator for &S8 { LL + type IntoIter = std::slice::Iter<'static, T>; -LL + type Iter = &T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter` method without an `IntoIterator` impl for `&S` - --> $DIR/iter_without_into_iter.rs:76:13 +error: `iter` method without an `IntoIterator` impl for `&S9` + --> $DIR/iter_without_into_iter.rs:75:5 | -LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { +LL | / pub fn iter(&self) -> std::slice::Iter<'_, T> { LL | | -LL | | todo!() -LL | | } - | |_____________^ +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&S` +help: consider implementing `IntoIterator` for `&S9` | -LL ~ -LL + impl IntoIterator for &S { +LL + +LL + impl IntoIterator for &S9 { LL + type IntoIter = std::slice::Iter<'_, T>; -LL + type Iter = &T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + } | -error: `iter_mut` method without an `IntoIterator` impl for `&mut S` - --> $DIR/iter_without_into_iter.rs:80:13 +error: `iter_mut` method without an `IntoIterator` impl for `&mut S9` + --> $DIR/iter_without_into_iter.rs:79:5 | -LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { +LL | / pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { LL | | -LL | | todo!() -LL | | } - | |_____________^ +LL | | todo!() +LL | | } + | |_____^ | -help: consider implementing `IntoIterator` for `&mut S` +help: consider implementing `IntoIterator` for `&mut S9` | -LL ~ -LL + impl IntoIterator for &mut S { +LL + +LL + impl IntoIterator for &mut S9 { LL + type IntoIter = std::slice::IterMut<'_, T>; -LL + type Iter = &mut T; -LL + fn into_iter() -> Self::IntoIter { +LL + type Item = &mut T; +LL + fn into_iter(self) -> Self::IntoIter { LL + self.iter() LL + } LL + }