Closed erikbrinkman closed 9 months ago
Could you provide output from cargo-expand (and the full error message for it)?
My guess is that the compiler cannot handle the Iterator bounds generated for the field types. https://github.com/taiki-e/iter-enum/blob/b4701422711834496824be87b24c492cfb000ae3/tests/expand/iterator.expanded.rs#L7-L9
If the field contains generics, these bounds are definitely needed, but it is okay to skip the generation of these bounds if the field does not contain generics.
Here's the output of cargo expand
I haven't had time yet to think about the extra bounds
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use iter_enum::Iterator;
use std::vec::IntoIter;
pub enum A {
A(Box<B>),
}
impl ::core::iter::Iterator for A
where
Box<B>: ::core::iter::Iterator,
{
type Item = <Box<B> as ::core::iter::Iterator>::Item;
#[inline]
fn next(&mut self) -> ::core::option::Option<Self::Item> {
match self {
A::A(x) => ::core::iter::Iterator::next(x),
}
}
#[inline]
fn size_hint(&self) -> (usize, ::core::option::Option<usize>) {
match self {
A::A(x) => ::core::iter::Iterator::size_hint(x),
}
}
#[inline]
fn count(self) -> usize {
match self {
A::A(x) => ::core::iter::Iterator::count(x),
}
}
#[inline]
fn last(self) -> ::core::option::Option<Self::Item> {
match self {
A::A(x) => ::core::iter::Iterator::last(x),
}
}
#[inline]
fn nth(&mut self, n: usize) -> ::core::option::Option<Self::Item> {
match self {
A::A(x) => ::core::iter::Iterator::nth(x, n),
}
}
#[inline]
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
fn collect<__U: ::core::iter::FromIterator<Self::Item>>(self) -> __U {
match self {
A::A(x) => ::core::iter::Iterator::collect(x),
}
}
#[inline]
fn partition<__U, __F>(self, f: __F) -> (__U, __U)
where
__U: ::core::default::Default + ::core::iter::Extend<Self::Item>,
__F: ::core::ops::FnMut(&Self::Item) -> bool,
{
match self {
A::A(x) => ::core::iter::Iterator::partition(x, f),
}
}
#[inline]
fn fold<__U, __F>(self, init: __U, f: __F) -> __U
where
__F: ::core::ops::FnMut(__U, Self::Item) -> __U,
{
match self {
A::A(x) => ::core::iter::Iterator::fold(x, init, f),
}
}
#[inline]
fn all<__F>(&mut self, f: __F) -> bool
where
__F: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
A::A(x) => ::core::iter::Iterator::all(x, f),
}
}
#[inline]
fn any<__F>(&mut self, f: __F) -> bool
where
__F: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
A::A(x) => ::core::iter::Iterator::any(x, f),
}
}
#[inline]
fn find<__P>(&mut self, predicate: __P) -> ::core::option::Option<Self::Item>
where
__P: ::core::ops::FnMut(&Self::Item) -> bool,
{
match self {
A::A(x) => ::core::iter::Iterator::find(x, predicate),
}
}
#[inline]
fn find_map<__U, __F>(&mut self, f: __F) -> ::core::option::Option<__U>
where
__F: ::core::ops::FnMut(Self::Item) -> ::core::option::Option<__U>,
{
match self {
A::A(x) => ::core::iter::Iterator::find_map(x, f),
}
}
#[inline]
fn position<__P>(&mut self, predicate: __P) -> ::core::option::Option<usize>
where
__P: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
A::A(x) => ::core::iter::Iterator::position(x, predicate),
}
}
}
pub enum B {
C(IntoIter<i32>),
B(A),
}
impl ::core::iter::Iterator for B
where
IntoIter<i32>: ::core::iter::Iterator,
A: ::core::iter::Iterator<Item = <IntoIter<i32> as ::core::iter::Iterator>::Item>,
{
type Item = <IntoIter<i32> as ::core::iter::Iterator>::Item;
#[inline]
fn next(&mut self) -> ::core::option::Option<Self::Item> {
match self {
B::C(x) => ::core::iter::Iterator::next(x),
B::B(x) => ::core::iter::Iterator::next(x),
}
}
#[inline]
fn size_hint(&self) -> (usize, ::core::option::Option<usize>) {
match self {
B::C(x) => ::core::iter::Iterator::size_hint(x),
B::B(x) => ::core::iter::Iterator::size_hint(x),
}
}
#[inline]
fn count(self) -> usize {
match self {
B::C(x) => ::core::iter::Iterator::count(x),
B::B(x) => ::core::iter::Iterator::count(x),
}
}
#[inline]
fn last(self) -> ::core::option::Option<Self::Item> {
match self {
B::C(x) => ::core::iter::Iterator::last(x),
B::B(x) => ::core::iter::Iterator::last(x),
}
}
#[inline]
fn nth(&mut self, n: usize) -> ::core::option::Option<Self::Item> {
match self {
B::C(x) => ::core::iter::Iterator::nth(x, n),
B::B(x) => ::core::iter::Iterator::nth(x, n),
}
}
#[inline]
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
fn collect<__U: ::core::iter::FromIterator<Self::Item>>(self) -> __U {
match self {
B::C(x) => ::core::iter::Iterator::collect(x),
B::B(x) => ::core::iter::Iterator::collect(x),
}
}
#[inline]
fn partition<__U, __F>(self, f: __F) -> (__U, __U)
where
__U: ::core::default::Default + ::core::iter::Extend<Self::Item>,
__F: ::core::ops::FnMut(&Self::Item) -> bool,
{
match self {
B::C(x) => ::core::iter::Iterator::partition(x, f),
B::B(x) => ::core::iter::Iterator::partition(x, f),
}
}
#[inline]
fn fold<__U, __F>(self, init: __U, f: __F) -> __U
where
__F: ::core::ops::FnMut(__U, Self::Item) -> __U,
{
match self {
B::C(x) => ::core::iter::Iterator::fold(x, init, f),
B::B(x) => ::core::iter::Iterator::fold(x, init, f),
}
}
#[inline]
fn all<__F>(&mut self, f: __F) -> bool
where
__F: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
B::C(x) => ::core::iter::Iterator::all(x, f),
B::B(x) => ::core::iter::Iterator::all(x, f),
}
}
#[inline]
fn any<__F>(&mut self, f: __F) -> bool
where
__F: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
B::C(x) => ::core::iter::Iterator::any(x, f),
B::B(x) => ::core::iter::Iterator::any(x, f),
}
}
#[inline]
fn find<__P>(&mut self, predicate: __P) -> ::core::option::Option<Self::Item>
where
__P: ::core::ops::FnMut(&Self::Item) -> bool,
{
match self {
B::C(x) => ::core::iter::Iterator::find(x, predicate),
B::B(x) => ::core::iter::Iterator::find(x, predicate),
}
}
#[inline]
fn find_map<__U, __F>(&mut self, f: __F) -> ::core::option::Option<__U>
where
__F: ::core::ops::FnMut(Self::Item) -> ::core::option::Option<__U>,
{
match self {
B::C(x) => ::core::iter::Iterator::find_map(x, f),
B::B(x) => ::core::iter::Iterator::find_map(x, f),
}
}
#[inline]
fn position<__P>(&mut self, predicate: __P) -> ::core::option::Option<usize>
where
__P: ::core::ops::FnMut(Self::Item) -> bool,
{
match self {
B::C(x) => ::core::iter::Iterator::position(x, predicate),
B::B(x) => ::core::iter::Iterator::position(x, predicate),
}
}
}
Thanks, I tried the output of cargo-expand in the playground, and removing the following bound seems to fix the error. So I think the way described in https://github.com/taiki-e/derive_utils/issues/47 (skip the generation of the trait bound) will work.
A: ::core::iter::Iterator<Item = <IntoIter<i32> as ::core::iter::Iterator>::Item>,
Fixed in derive_utils 0.14.0 & iter-enum 1.1.2.
This library seems to enter an infinite loop when trying to analyze recursive structures, even if the manual implementation works. I'm not super familiar with proc macros, so looking around a bit didn't turn up an obvious fix, but here's a reproduceable error:
and the corresponding implementation that works that I assumed the macro would generate: