Hi,
I'd like to start with the example that does not work:
pub struct S1;
pub trait T1<'a> {
fn exec(&mut self, v: &'a [u8]);
}
impl<'a> T1<'a> for S1 {
fn exec(&mut self, v: &'a [u8]) {
println!("{:?}", v[0]);
}
}
pub fn t1v<'a, T: T1<'a>>(vec: &'a[u8], t: &'a mut T) {
for i in &[0, 1, 2][..] {
t1(&vec[*i as usize..], t);
}
}
pub fn t1<'a, T: T1<'a>>(v: &'a [u8], t: &'a mut T) -> Option<()> {
t.exec(v);
Some(())
}
fn main() {
let mut t = S1;
let vec1 = b"12345";
t1v(&vec1[..], &mut t);
}
src/test.rs:17:33: 17:34 error: cannot borrow `*t` as mutable more than once at a time [E0499]
src/test.rs:17 t1(&vec[*i as usize..], t);
^
src/test.rs:17:33: 17:34 help: run `rustc --explain E0499` to see a detailed explanation
src/test.rs:17:33: 17:34 note: previous borrow of `*t` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*t` until the borrow ends
src/test.rs:17 t1(&vec[*i as usize..], t);
^
src/test.rs:19:2: 19:2 note: previous borrow ends here
src/test.rs:15 pub fn t1v<'a, T: T1<'a>>(vec: &'a[u8], t: &'a mut T) {
src/test.rs:16 for i in &[0, 1, 2][..] {
src/test.rs:17 t1(&vec[*i as usize..], t);
src/test.rs:18 }
src/test.rs:19 }
^
error: aborting due to previous error
In my understanding, I failed to explain to compiler that the borrow of t that is originated at t1(..., t); ends right then and there. This is probably because lifetime of t is specified to be any. Is there a way to tell compiler that no matter lifetime the borrow really ends there?
I can work around this problem by excluding lifetime from Trait definition. So the working example looks like this:
pub struct S1;
pub trait T2 {
fn exec<'a>(&mut self, v: &'a [u16]);
}
impl T2 for S1 {
fn exec<'a>(&mut self, v: &'a [u16]) {
println!("{:?}", v[0]);
}
}
pub fn t2v<'a, T: T2>(vec: &'a[u16], t: &'a mut T) {
for i in &[0, 1, 2][..] {
t2(&vec[*i as usize..], t);
}
}
pub fn t2<'a, T: T2>(v: &'a [u16], t: &'a mut T) -> Option<()> {
t.exec(v);
Some(())
}
fn main() {
let mut t = S1;
let vec1 = b"12345";
let vec2 = [1, 2, 3, 4, 5];
t2v(&vec2[..], &mut t);
}
Running `target/debug/test`
1
2
3
However my question is regarding the first example:
What is the most "rustian" way to handle multiple mutual borrow with any lifetime in the scope of iteration in rust?
Is it possible without interior mutability?
Thank you.