How should I refactor my code to make it work with the borrow checker?
Either left
or right
is borrowed exclusively as ret
and later the in the for loop, ret
is mutated and also requiring the access of left
and right
. I understand the borrowing rules but I just couldn't figure out how to make it work.
// playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=892b27995aa72045a1e7c607fbe675dd
#![allow(unused)]
use std::cmp::min;
struct Beading {
thickness: i64,
widths: Vec<i64>,
locations: Vec<usize>,
}
fn interpolate<'a>(left: &'a mut Beading, ratio: f64, right: &'a mut Beading) -> &'a Beading {
let left_len = left.widths.len();
let right_len = right.widths.len();
// exclusive borrowing
let ret: &mut Beading = if left.thickness > right.thickness {
left
} else {
right
};
// problems
for idx in 0..min(left_len, right_len) {
if left.widths[idx] == 0 || right.widths[idx] == 0 {
ret.widths[idx] = todo!();
} else {
ret.widths[idx] = todo!();
}
ret.locations = todo!();
}
ret
}
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `left.widths` as immutable because it is also borrowed as mutable
--> src/lib.rs:23:12
|
10 | fn interpolate<'a>(left: &'a mut Beading, ratio: f64, right: &'a mut Beading) -> &'a Beading {
| -- lifetime `'a` defined here
...
16 | left
| ---- mutable borrow occurs here
...
23 | if left.widths[idx] == 0 || right.widths[idx] == 0 {
| ^^^^^^^^^^^ immutable borrow occurs here
...
31 | ret
| --- returning this value requires that `*left` is borrowed for `'a`
error[E0502]: cannot borrow `right.widths` as immutable because it is also borrowed as mutable
--> src/lib.rs:23:37
|
10 | fn interpolate<'a>(left: &'a mut Beading, ratio: f64, right: &'a mut Beading) -> &'a Beading {
| -- lifetime `'a` defined here
...
18 | right
| ----- mutable borrow occurs here
...
23 | if left.widths[idx] == 0 || right.widths[idx] == 0 {
| ^^^^^^^^^^^^ immutable borrow occurs here
...
31 | ret
| --- returning this value requires that `*right` is borrowed for `'a`