0

The code below compiles only when line 11 is commented:

#[allow(warnings)]
fn main() {
    let mut content = String::from("Hello world!");

    let snapshot = get_slice(&content); // immutable borrow
    println!("content is : {}", &content);

    content.clear(); // mutable borrow fn clear(&mut self)

    println!("snapshot is : {}", snapshot); // should be commented for this to compile
}

fn get_slice(part: &str) -> &str {
    &part[0..5]
}

The compiler says:

error[E0502]: cannot borrow `content` as mutable because it is also borrowed as immutable
  --> src/main.rs:8:5
   |
5  |     let snapshot = get_slice(&content); // immutable borrow
   |                              -------- immutable borrow occurs here
...
8  |     content.clear(); // mutable borrow fn clear(&mut self)
   |     ^^^^^^^^^^^^^^^ mutable borrow occurs here
9  | 
10 |     println!("snapshot is : {}", snapshot); // should be commented for this to compile
   |                                  -------- immutable borrow later used here
  1. What happens to snapshot after content.clear() ? Is it dropped ?
  2. It seems to me that both immutable and mutable borrows are happening regardless of line 11. But, why is the compiler throwing an error only when it is not commented?
  3. Is this because of the rule any borrow must last for a scope no greater than that of the owner. If so, can you please elaborate more to clarify this?
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
devio
  • 1,147
  • 5
  • 15
  • 41
  • Rust drops references as soon as possible, so if the snapshot `println` is commented then `snapshot` gets dropped immediately due to not being used. – Aplet123 Feb 17 '21 at 18:51
  • Alright. So, when I comment the last `println`, `content` is still both a mutable and an immutable borrow; why isn't the compiler throwing an error in this case ? – devio Feb 17 '21 at 19:01
  • It's hard to answer multiple questions made in one post. Please separate them into multiple questions so that we can help you better and so that your questions will help others in the future that have one of the same questions as you! – Shepmaster Feb 17 '21 at 19:04
  • See also all the [questions linked to the duplicate](https://stackoverflow.com/questions/linked/50251487?sort=newest) – Shepmaster Feb 17 '21 at 19:06
  • 1
    @occulti no, when you comment the last `println` content is an owned variable with three different and non-overlapping borrows: one immutable borrow to create `snapshot` which is immediately released (because `snapshot` is not used so it can be dropped immediately), a second immutable borrow for `println` (the explicit borrow is completely unnecessary incidentally, `println` borrows implicitly) which ends when the printing is done, and finally a mutable borrow which lasts for the extent of the `clear` call. – Masklinn Feb 17 '21 at 19:14
  • What you're saying *used* to be the case before non-lexical borrow were implemented: a borrow (at least an explicit one, I don't think that was the case for method calls?) would last until the end of the block it was created in. – Masklinn Feb 17 '21 at 19:15
  • @Shepmaster : my questions are linked to each other... – devio Feb 17 '21 at 19:20

0 Answers0