Skip to content
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

How to use generic ViewMut with_id? #191

Open
SSSxCCC opened this issue Feb 1, 2024 · 1 comment
Open

How to use generic ViewMut with_id? #191

SSSxCCC opened this issue Feb 1, 2024 · 1 comment

Comments

@SSSxCCC
Copy link

SSSxCCC commented Feb 1, 2024

#157 use some bounds to make generic ViewMut iterator work, but I still can not make generic ViewMut with_id work:

trait MutTrait {
    fn mutmut(&mut self);
}

fn expected<T: Component + MutTrait>(mut v: ViewMut<T>)
where
    for<'a, 'b> &'a mut ViewMut<'b, T>: IntoIter,
    for<'a, 'b> <<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter as Iterator>::Item: std::ops::DerefMut<Target = T>,
{
    for mut x in (&mut v).iter() {
        x.mutmut();
    }
}

fn weird<T: Component + MutTrait>(mut v: ViewMut<T>)
where
    for<'a, 'b> &'a mut ViewMut<'b, T>: IntoIter,
    for<'a, 'b> <<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter as Iterator>::Item: std::ops::DerefMut<Target = T>,
    for<'a, 'b> <&'a mut ViewMut<'b, T> as shipyard::IntoIter>::IntoIter: IntoWithId,
    for<'a, 'b> WithId<<&'a mut ViewMut<'b, T> as shipyard::IntoIter>::IntoIter>: Iterator,
    for<'a, 'b> <WithId<<&'a mut ViewMut<'b, T> as shipyard::IntoIter>::IntoIter> as Iterator>::Item: std::ops::DerefMut<Target = (EntityId, dyn std::ops::DerefMut<Target = T>)>
{
    for (id, x) in (&mut v).iter().with_id() { // error: expected associated type, found `(_, _)`
        x.mutmut();
    }
}

I try to add bounds but I still can not make it work.
Please help me, thanks!

@leudz
Copy link
Owner

leudz commented Feb 9, 2024

This should work but doesn't for some lifetime reason.

// `IntoAbstract` would have to be implemented for the type `&'0 mut shipyard::ViewMut<'1, Component1>`, for any two lifetimes `'0` and `'1`...
// ...but `IntoAbstract` is actually implemented for the type `&mut shipyard::ViewMut<'2, Component1>`, for some specific lifetime `'2` 
fn weird<T: Component + MutTrait>(mut v: ViewMut<T>)
where
    for<'a, 'b> &'a mut ViewMut<'b, T>: IntoIter,
    for<'a, 'b> <<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter as Iterator>::Item:
        std::ops::DerefMut<Target = T>,
    for<'a, 'b> <&'a mut ViewMut<'b, T> as IntoIter>::IntoIter: Iterator + LastId,
{
    for (id, mut x) in WithId((&mut v).iter()) {
        x.mutmut();
    }
}

And turns out the code in the issue you linked has the same issue. So I'm not sure it ever worked 😰


In theory something like this should also work:

fn weird<T: Component + MutTrait>(mut v: ViewMut<T>)
where
    for<'a, 'b> &'a mut ViewMut<'b, T>: IntoIter,
    for<'a, 'b> <<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter as Iterator>::Item:
        std::ops::DerefMut<Target = T>,
    // binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
    // binding for associated type `Item` references lifetime `'b`, which does not appear in the trait input types
    for<'a, 'b> WithId<<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter>: Iterator<
        Item = (
            EntityId,
            <<&'a mut ViewMut<'b, T> as IntoIter>::IntoIter as Iterator>::Item,
        ),
    >,
{
    for (id, mut x) in (&mut v).iter().with_id() {
        x.mutmut();
    }
}

But it triggers this issue rust-lang/rust#49601.
And I think it would also trigger the other one.
So in conclusion I don't know how to write a generic ViewMut iterator, sorry.

# 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