Here is a minimal working example, I have a NumberFactory
responsible for creating special Number
s, but using it is kinda counter-intuitive to me.
struct NumberFactory {
max_id: usize,
}
#[derive(Copy, Clone, Debug)]
struct Number {
id: usize,
scalar: f32,
}
impl Number {
fn new(id: usize, scalar: f32) -> Self {
Self { id, scalar }
}
}
impl NumberFactory {
fn new() -> Self {
Self { max_id: 0 }
}
fn from_scalar(&mut self, scalar: f32) -> Number {
let id = self.max_id;
self.max_id += 1;
Number::new(id, scalar)
}
fn add(&mut self, a: Number, b: Number) -> Number {
let id = self.max_id;
self.max_id += 1;
Number::new(id, a.scalar + b.scalar)
}
}
fn main() {
let mut nf = NumberFactory::new();
let x = nf.from_scalar(1.0);
let y = nf.from_scalar(2.0);
let z = nf.add(x, y);
println!("z: {:?}", z);
}
If instead I try to write:
fn main() {
let mut nf = NumberFactory::new();
let x = nf.from_scalar(1.0);
let z = nf.add(x, nf.from_scalar(2.0));
println!("z: {:?}", z);
}
I get the error:
39 | let z = nf.add(x, nf.from_scalar(2.0));
| ----------^^^^^^^^^^^^^^^^^^^-
| | | |
| | | second mutable borrow occurs here
| | first borrow later used by call
| first mutable borrow occurs here
|
help: try adding a local storing this argument...
I think I understand the error, in Rust's logic, but I find it weird.
Wouldn't nf.from_scalar(2.0)
have returned before nf.add
is called, hence not borrowing nf
twice at the same time?
Is it due to Rust's method calling conventions?
In C, both arguments would have been put on the stack before the call to add
if I remember correctly, so nf
wouldn't have been borrowed twice (if the concept existed in C).
Rust's help text here is perfect here, any reason why this sort of optimization cannot be performed automatically?