Skip to content

DoubleEndedIterator implementation causes overflow libcore build #88

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
compiler-errors opened this issue Feb 3, 2024 · 3 comments
Closed

Comments

@compiler-errors
Copy link
Member

compiler-errors commented Feb 3, 2024

Minimized when trying to build core:

#![feature(associated_type_bounds)]

use std::iter::FlatMap;

trait DoubleEndedIterator: Iterator {
    fn next_back(&mut self) -> Option<Self::Item>;
}

impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
where
    F: FnMut(I::Item) -> U,
    U: IntoIterator,
    <U as IntoIterator>::IntoIter: DoubleEndedIterator, //~ This line is bad, specifically b/c `DoubleEndedIterator` has the `Iterator` supertrait, I believe.
{
    fn next_back(&mut self) -> Option<U::Item> {
        todo!()
    }
}

I think it's because the solver is having trouble projecting <<U as IntoIterator>::IntoIter as Iterator>::Item into <U as IntoIterator>::Item. It should be possible to do that via this item bound type IntoIter: Iterator<Item = Self::Item>.

@compiler-errors compiler-errors changed the title Two choices of rigid projections Two choices of rigid projections causes overflow? Feb 3, 2024
@compiler-errors compiler-errors changed the title Two choices of rigid projections causes overflow? DoubleEndedIterator implementation causes overflow libcore build Feb 3, 2024
@compiler-errors
Copy link
Member Author

compiler-errors commented Feb 3, 2024

Ah, it has to do with the blanket impl I: IntoIterator :- I: Iterator

trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;
}

trait IntoIterator {
    type IntoIter: Iterator<Item = Self::Item>;
    type Item;
}

/* Uncomment this to make it fail:
impl<I: Iterator> IntoIterator for I {
    type Item = I::Item;
    type IntoIter = I;
}
*/

trait DoubleEndedIterator: Iterator {
    fn next_back(&mut self) -> Option<Self::Item>;
}

struct Foo<U>(U);

impl<U> Iterator for Foo<U> where U: IntoIterator {
    type Item = U::Item;

    fn next(&mut self) -> Option<Self::Item> { todo!() }
}

impl<U> DoubleEndedIterator for Foo<U>
where
    U: IntoIterator,
    <U as IntoIterator>::IntoIter: DoubleEndedIterator,
{
    fn next_back(&mut self) -> Option<U::Item> {
        todo!()
    }
}

fn main() {}

@compiler-errors
Copy link
Member Author

🤔 is this #76?

@lcnr
Copy link
Contributor

lcnr commented Feb 8, 2024

jup, it's #76

@lcnr lcnr closed this as completed Feb 8, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants