Why don't you have to be explicit about passing a primitive by reference?


#1

In the code below I get an error saying that an immutable borrow occurred in the println!. But as you can see I’m not passing by reference, which would be &x. So my questions are:

  1. Why does Rust do not enforce that you pass by reference explicitly?

  2. Is there such a thing as pass by copy for primitives?

    fn main() {
    let mut x = 5;
    let y = &mut x;

     *y += 1;
    
     println!("{}", x);
    

    }


#2

The println! macro implicitly borrows everything. Check out this StackOverflow question for an explanation of how.


#3

Thanks for the great link. However my question 2) still remains => Why can’t I just pass a primitive by copy, in other words, without any borrowing?


#4

Any access to x is invalid while it is mutably borrowed (because mutable borrowing is exclusive). So copy, move or borrow of x in that location would all error, because y is still in scope.


#5

Thanks so much for the explanation. For the record:

fn main() {
    let x = 5;
    let y = &x;
    take(x);
}

fn take(x: i32) {

}

Works well, because you can take as many immutable borrows (or copies, or moves) as you want.

But:

fn main() {
    let mut x = 5;
    let y = &mut x;
    take(x);
}

fn take(x: i32) {

}

Does not work because a mutable borrow is exclusive as you said.


#6

Yes. The first example will be an error if x is non-Copy (Can’t move while being borrowed), for example if it’s a String::from("xyz").