diff --git a/src/runtime.rs b/src/runtime.rs index f3cdded..0f314ea 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -45,11 +45,8 @@ impl BitOr for HasIterator { /// whichever impl happens to be applicable. Calling that method repeatedly on /// the returned value should be idempotent. pub mod ext { - use super::RepInterp; use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter}; use crate::ToTokens; - use core::slice; - use std::collections::btree_set::{self, BTreeSet}; /// Extension trait providing the `quote_into_iter` method on iterators. pub trait RepIteratorExt: Iterator + Sized { @@ -60,6 +57,16 @@ pub mod ext { impl RepIteratorExt for T {} + /// Extension trait providing the `quote_into_iter` method on containers + /// implementing IntoIterator. + pub trait RepIntoIteratorExt: IntoIterator + Copy + Sized { + fn quote_into_iter(self) -> (Self::IntoIter, HasIter) { + (self.into_iter(), HasIter) + } + } + + impl RepIntoIteratorExt for T {} + /// Extension trait providing the `quote_into_iter` method for /// non-iterable types. These types interpolate the same value in each /// iteration of the repetition. @@ -77,62 +84,6 @@ pub mod ext { } impl RepToTokensExt for T {} - - /// Extension trait providing the `quote_into_iter` method for types that - /// can be referenced as an iterator. - pub trait RepAsIteratorExt<'q> { - type Iter: Iterator; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter); - } - - impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - ::quote_into_iter(*self) - } - } - - impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - ::quote_into_iter(*self) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] { - type Iter = slice::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec { - type Iter = slice::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet { - type Iter = btree_set::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - self.0.quote_into_iter() - } - } } // Helper type used within interpolations to allow for repeated binding names. @@ -150,11 +101,12 @@ impl RepInterp { } } -impl Iterator for RepInterp { +impl IntoIterator for RepInterp { type Item = T::Item; + type IntoIter = T::IntoIter; - fn next(&mut self) -> Option { - self.0.next() + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() } } diff --git a/tests/ui/not-repeatable.stderr b/tests/ui/not-repeatable.stderr index bf62515..5860403 100644 --- a/tests/ui/not-repeatable.stderr +++ b/tests/ui/not-repeatable.stderr @@ -1,35 +1,57 @@ error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied - --> tests/ui/not-repeatable.rs:7:9 - | -3 | struct Ipv4Addr; - | --------------- - | | - | method `quote_into_iter` not found for this struct - | doesn't satisfy `Ipv4Addr: Iterator` - | doesn't satisfy `Ipv4Addr: ToTokens` - | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt` - | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt` + --> tests/ui/not-repeatable.rs:7:9 + | +3 | struct Ipv4Addr; + | --------------- + | | + | method `quote_into_iter` not found for this struct + | doesn't satisfy `Ipv4Addr: Copy` + | doesn't satisfy `Ipv4Addr: IntoIterator` + | doesn't satisfy `Ipv4Addr: Iterator` + | doesn't satisfy `Ipv4Addr: ToTokens` + | doesn't satisfy `Ipv4Addr: ext::RepIntoIteratorExt` + | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt` + | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt` ... -7 | _ = quote! { #(#ip)* }; - | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `Ipv4Addr: Iterator` - which is required by `Ipv4Addr: ext::RepIteratorExt` - `&Ipv4Addr: Iterator` - which is required by `&Ipv4Addr: ext::RepIteratorExt` - `Ipv4Addr: ToTokens` - which is required by `Ipv4Addr: ext::RepToTokensExt` - `&mut Ipv4Addr: Iterator` - which is required by `&mut Ipv4Addr: ext::RepIteratorExt` +7 | _ = quote! { #(#ip)* }; + | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Ipv4Addr: Iterator` + which is required by `Ipv4Addr: ext::RepIteratorExt` + `Ipv4Addr: IntoIterator` + which is required by `Ipv4Addr: ext::RepIntoIteratorExt` + `Ipv4Addr: Copy` + which is required by `Ipv4Addr: ext::RepIntoIteratorExt` + `&Ipv4Addr: Iterator` + which is required by `&Ipv4Addr: ext::RepIteratorExt` + `&Ipv4Addr: IntoIterator` + which is required by `&Ipv4Addr: ext::RepIntoIteratorExt` + `Ipv4Addr: ToTokens` + which is required by `Ipv4Addr: ext::RepToTokensExt` + `&mut Ipv4Addr: Iterator` + which is required by `&mut Ipv4Addr: ext::RepIteratorExt` + `&mut Ipv4Addr: IntoIterator` + which is required by `&mut Ipv4Addr: ext::RepIntoIteratorExt` + `&mut Ipv4Addr: Copy` + which is required by `&mut Ipv4Addr: ext::RepIntoIteratorExt` note: the following traits must be implemented - --> src/to_tokens.rs - | - | pub trait ToTokens { - | ^^^^^^^^^^^^^^^^^^ - | - ::: $RUST/core/src/iter/traits/iterator.rs - | - | pub trait Iterator { - | ^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) + --> src/to_tokens.rs + | + | pub trait ToTokens { + | ^^^^^^^^^^^^^^^^^^ + | + ::: $RUST/core/src/iter/traits/collect.rs + | + | pub trait IntoIterator { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $RUST/core/src/iter/traits/iterator.rs + | + | pub trait Iterator { + | ^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Ipv4Addr` with `#[derive(Clone, Copy)]` + | +3 | #[derive(Clone, Copy)] + |