Search code examples
rustborrow-checkerownership

Issue with string borrowing and println in Rust


I have been learning rust lately and I am unable to figure out something

Why does this work

fn main() {
    let mut s = String::from("hello");
    println!("{}", &s);
    let r = &s;
    
    println!("{}", r);
    let x = &mut s;
    println!("{}", x);
    }

but this doesn't

fn main() {
    let mut s = String::from("hello");
    println!("{}", &s);
    let r = &s;
    let x = &mut s;
    println!("{}", r);
    
    println!("{}", x);
    }

It gives the following error:

cannot borrow `s` as mutable because it is also borrowed as immutable

If println takes the ownership of the string and doesn't return it, why does the first snippet work. Aren't we doing the same thing in both cases?


Solution

  • Thank you for the suggestions.

    To summarise, &mut s is an exclusive borrow, i.e. it doesn't allow any other kind of borrow in the same scope.

    The first snippet works due to lexical scoping , i.e. , the compiler is smart enough to figure out that r is not being used after &mut s.

    fn main() {
        let mut s = String::from("hello");
        println!("{}", &s);
        let r = &s;
        
        println!("{}", r);
        let x = &mut s;
        println!("{}", x);
        }
    

    However, if we used this snippet instead of the first one. The code will give the same error as r is being used again &mut s which is not allowed in the language.

    fn main() {
        let mut s = String::from("hello");
        println!("{}", &s);
        let r = &s;
        
        println!("{}", r);
        let x = &mut s;
        println!("{}", x);
        
        println!("{}", r);
        }