[Solved] Iterator borrowing from itself and abstracting over mutability

#1

Hello everyone, I’m trying to make something like this:

let iter = my_struct.iter::<(A, B)>();
while let Some((a, b)) = iter.next() {}

The tuple can be (&T, &U), (&mut T, &U), (&T, &mut U) or (&mut T, &mut U) and iter.next() has to borrow from itself.

Given these requirements I can’t use std’s Iterator but it’s not a big deal. This article presents 3.5 ways to make an iterator borrowing from itself, the last one is nightly only and doesn’t work well with what I’m trying to do so I tried the first 2.5.

My issue is that I can’t get the right lifetime, I only get my_struct’s lifetime.
I don’t even know if that’s possible, I made it work by using a macro that basically counted in binary (since mut can be thought as 1 and no mut as 0) but I generated so much code it took 50sec to build with tuples only going to size 6.
This is the closest I got using method 2.5.

Like I said, I don’t know if it’s possible. If a lifetime wizard could tell me and maybe point me to the right direction it would be awesome.
Thank you.

0 Likes

#3

Would something like this work?

https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=ecd3c3ba2e61e0f927b8e08ab83184a7

*note: this is beta because Rust 1.33 has an ICEs with this on stable, but it got fixed in the 1.34 beta, which will turn into stable by the end of the week

1 Like

#4

Thank you so much!!!
Well, it didn’t work because Foo borrows from an other struct and when it’s an immutable burrow I can’t deref and reborrow it as mutable.
But with what you showed, I was able to make it work. I just added a lifetime to GetHelper and since next() doesn’t require an associated type, I just removed the Iterator trait altogether.
Now, it compiles in just 3sec with tuples of size <= 6 which is far better than 50sec.

1 Like