Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I call a mutating function more than once? [duplicate]

This is based on my previous question.

I have code that is failing with borrow checker error and I reduced it as much as I could. This is the result:

struct MyStruct<'a> {
    s: &'a str,
}

impl<'a> MyStruct<'a> {
    fn foo(&'a mut self) {}
}

fn main() {
    let mut m = MyStruct { s: "aaa" };

    m.foo();
    m.foo();
}

It is failing with:

error[E0499]: cannot borrow `m` as mutable more than once at a time
  --> src/main-x.rs:13:5
   |
12 |     m.foo();
   |     - first mutable borrow occurs here
13 |     m.foo();
   |     ^
   |     |
   |     second mutable borrow occurs here
   |     first borrow later used here

The code was reduced so much that it does nothing useful and could be fixed for example by removing the 'a lifetime from the foo function. But I would like to understand why is the code not ok as it is.

My understanding is that MyStruct contains reference to str of some lifetime 'a and foo can be called with self pointing to MyStruct of the same lifetime. I don't see why is m considered mutably borrowed after the first call to foo.

like image 377
michalsrb Avatar asked May 09 '19 13:05

michalsrb


1 Answers

When you declare foo as

 fn foo(&'a mut self) {}

you say the mutable borrow of self has the same lifetime 'a as the embedded string. So it stays borrowed as long as the struct lives. Calling foo is like definitely giving away the ownership of the struct.

You can fix it by declaring foo as

 fn foo(&mut self) {}
like image 151
Denys Séguret Avatar answered Nov 15 '22 10:11

Denys Séguret