Probably not the right place to ask this, but what the hell. I've been battling with the borrow checker for too long. I'm try to pass a slice of f32s to a function that will use each one in a closure, but I have a lifetime problem I can't seem to solve. This code is part of an impl block for a funtion that implements a trait with a modify_amplitude function:
pub fn set_amplitudes(&mut self, weights: &[f32]) {
for (i, v) in self.waves.iter_mut().enumerate() {
v.0.modify_amplitude(Rc::new(|_| weights[i]));
}
}
error[E0597]: `weights` does not live long enough
--> src/lib.rs:428:46
|
428 | v.0.modify_amplitude(Rc::new(|_| weights[i]));
| ------------^^^^^^^----
| | | |
| | | borrowed value does not live long enough
| | value captured here
| cast requires that `weights` is borrowed for `'static`
429 | }
430 | }
| - `weights` dropped here while still borrowed
rror[E0597]: weight does not live long enough
--> src/lib.rs:429:46
|
429 | v.0.modify_amplitude(Rc::new(|_| weight));
| ------------^^^^^^-
| | | |
| | | borrowed value does not live long enough
| | value captured here
| cast requires that weight is borrowed for 'static
430 | }
431 | }
| - weight dropped here while still borrowed
I think the problem you're having is because you're trying to wrap the closure in a reference counted type, which will require a lifetime for your weights reference. You would probably need to clone the weights and move them into the closure.
And when you use dyn Trait without specifying a lifetime, the compiler automatically inserts 'static. This means you've declared that it can only accept closures that contain no references to outside the closure. In your case, the closure contains a reference to weights, thus the error.
What are you trying to do? The closure will need to take ownership of something instead.
@trentj That will not work because weights doesn't live long enough for you to store a reference to it in the wave. For that to be the case, the weights reference would have to outlive the wave. You can't fix this issue by randomly inserting lifetimes in various places.
The signature I suggested doesn't allow you to store the Rc inside self; it just relaxes the 'static bound. From glancing at the code it does not look as if the Rc is ever stored inside self, so it's analogous to
Do you need to modify the integer? What do you think of this?
pub fn set_amplitudes(&mut self, weights: &[f32]) {
for (i, v) in self.waves.iter_mut().enumerate() {
// make a copy
let val = weights[i];
// move the copy into the closure
v.0.modify_amplitude(Rc::new(move |_| val));
}
}
If you do need to modify it, please explain what operations you might need to perform.
error[E0597]: val does not live long enough
--> src/lib.rs:430:46
|
430 | v.0.modify_amplitude(Rc::new(|_| val));
| ------------^^^-
| | | |
| | | borrowed value does not live long enough
| | value captured here
| cast requires that val is borrowed for 'static
431 | }
432 | }
| - val dropped here while still borrowed