In Rust, you can tell whether something is borrowed from the call site, without having to look at the function being called. If a function takes a reference (`&T`), then the caller must pass a reference. There's no implicit by-referencing as in C++'s `&` types.
(I realize you, saagarjha, probably know this already -- this is more a note to other readers.)
You'll get a compile-time error explaining the situation, yes, including documentation links and possible fixes. The differences between the versions are minimal.
fn add1(x: Thing) -> Thing {
x + 1
}
fn add2(x: &Thing) -> Thing {
x + 2
}
This works on the assumption that whatever "+ 1" really means doesn't itself need ownership of x, e.g. because it mutates it. If it does, then you'll get an error. Or you could do this:
fn add3(x: &mut Thing) {
x.add(3)
}
Which, presumably, modifies x instead of returning a copy. It's your job to make sure it makes sense to do that, but Rust has another trick in its pockets:
let y = add1(x); // Works; takes ownership.
let z = add2(&y); // Works, and doesn't take ownership.
let zz = add2(&y); // So you can do it twice. (Y tho?)
let h = add3(&y); // Compile-time error!
let hh = add3(&mut y); // Works. You need to specify that you're fine with y being mutated.
The first will take ownership of the thing you pass in, so you can't do something like this:
let x = vec![1, 2, 3];
let y = add1(x);
let z = add1(x); // error[E0382]: use of moved value: `x`
but the follow code is OK, because the function just borrows the value instead of owning (and destroying) it:
let x = vec![1, 2, 3];
let y = add1_borrow(&x);
let z = add1_borrow(&x);
This is legal too:
let x = vec![1, 2, 3];
let y = add1_borrow(&x);
let z = add1(x);
but as before you can't use x after this.
(Note, I chose Vec here because Vec does not implement Copy: if I used i32 it would just copy the value in the non-borrowing case, which would make the code fine as no ownership would be transferred.)
It won't compile, because the compiler keeps track of where you moved the value and notices that x now has no value. If you want the function to borrow the argument instead, make it take a reference, &x.
(I realize you, saagarjha, probably know this already -- this is more a note to other readers.)