Borrowing as mutable while it is immutable borrowed

Rust mentions that nothing can be mutable borrowed WHILE it is immutably borrowed. But the code beneath (fn first_word() returns the first word in a string) does not throw a compile time error unless I uncomment the (now commented) println!(). The compile time error only shows when I actually use the variable word within the println!(). Is that supposed to happen?

Also what change would I need to make such that code the returned first word of the string doesn't change no matter what I do with the original string?
I'm new to asking questions on a forum about a language and I'm sorry if the question is a little ambiguously put

fn main() {
    let mut s = String::from("Hello world");

    let word = first_word(&s);
    s.clear();
    // println!("the first word is {} ", word);
}

fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}

When you call s.clear() the compiler sees that another reference exists to s which would normally not be allowed. However it also sees that reference is never used again, so it drops the reference early to allow s.clear() to work.

When you add the println you're interleaving usages of those two references so it can't perform that early drop at s.clear() and can only error.

I'm not sure I follow the second part of your question. The point of the borrowing rules is precisely that a shared reference shouldn't be able to observe any changes to it's value (barring interior mutability). If you want to make the println work you can call to_string() on the output of first_word to force a copy of that string slice so it's no longer borrowed at all

4 Likes

That cleared it up more or less, thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.