While implementing a crate of mine, I encountered a strange compiler error.
I implemented a trait of the crate le-stream for an array like so:
impl<T, const SIZE: usize> ToLeBytes for [T; SIZE]
where
T: ToLeBytes,
{
type Iter = FlatMap<IntoIter<T, SIZE>, <T as ToLeBytes>::Iter, fn(T) -> <T as ToLeBytes>::Iter>;
fn to_le_bytes(self) -> Self::Iter {
self.into_iter().flat_map(<T as ToLeBytes>::to_le_bytes)
}
}
So far, so good. But then I tried the same approach for heapless::Vec
:
#[cfg(feature = "heapless")]
impl<T, const SIZE: usize> ToLeBytes for heapless::Vec<T, SIZE>
where
T: Sized + ToLeBytes,
{
type Iter = std::iter::Chain<
size_prefix_iterator::SizePrefixIterator,
FlatMap<
<Self as IntoIterator>::IntoIter,
<T as ToLeBytes>::Iter,
fn(T) -> <T as ToLeBytes>::Iter,
>,
>;
fn to_le_bytes(self) -> Self::Iter {
size_prefix_iterator::SizePrefixIterator::new(self.len(), SIZE)
.chain(self.into_iter().flat_map(<T as ToLeBytes>::to_le_bytes))
}
}
Resulting in this error:
error[E0308]: mismatched types
--> src/to_le_bytes/impls.rs:134:9
|
133 | fn to_le_bytes(self) -> Self::Iter {
| ---------- expected `std::iter::Chain<SizePrefixIterator, FlatMap<heapless::vec::IntoIter<T, SIZE>, <T as ToLeBytes>::Iter, fn(T) -> <T as ToLeBytes>::Iter>>` because of return type
134 | / size_prefix_iterator::SizePrefixIterator::new(self.len(), SIZE)
135 | | .chain(self.into_iter().flat_map(<T as ToLeBytes>::to_le_bytes))
| |____________________________________________________________________________^ expected fn pointer, found fn item
|
= note: expected struct `std::iter::Chain<_, FlatMap<_, _, fn(_) -> _>>`
found struct `std::iter::Chain<_, FlatMap<_, _, fn(_) -> _ {<T as ToLeBytes>::to_le_bytes}>>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `le-stream` (lib) due to 1 previous error
If I just add a trivial cast, however, it compiles:
#[cfg(feature = "heapless")]
impl<T, const SIZE: usize> ToLeBytes for heapless::Vec<T, SIZE>
where
T: Sized + ToLeBytes,
{
type Iter = std::iter::Chain<
size_prefix_iterator::SizePrefixIterator,
FlatMap<
<Self as IntoIterator>::IntoIter,
<T as ToLeBytes>::Iter,
fn(T) -> <T as ToLeBytes>::Iter,
>,
>;
fn to_le_bytes(self) -> Self::Iter {
#[allow(trivial_casts)]
size_prefix_iterator::SizePrefixIterator::new(self.len(), SIZE).chain(
self.into_iter()
.flat_map(<T as ToLeBytes>::to_le_bytes as _),
)
}
}
Why is this necessary when implementing the iterator for the heapless::Vec
but not for an array?