I get a "error[E0499]: cannot borrow settings as mutable more than once at a time" at settings.save_settings() in main. I can understand this, because each call to a settings function has a self borrow and the self borrow for settings.pwm_from_setting() exists as long as the struct, i.e. until the end of the program.
If I remove the lifetime annotation and declare
fn pwm_from_setting(& mut self);
I get a "error: lifetime may not live long enough" for the "self.pwm" assignment.
Pwm<'a> has its own lifetime annotation and this seems to be the problem. But this is a type from another library and I cannot simply remove this. But why do I need to chain the Pwm lifetime to the self borrow lifetime. Isn't a struct field owned by the struct and shares the lifetime of the struct?
I could make Pwm static in my application but I am intrigued if there is a better solution.
impl<'a> Type<'a> { fn f(&'a mut self … is essentially never what you actually want. Any &'a mut &'a … generally falls in the same bucket[1]. When you call PwmGuiData<'a>::pwm_from_setting, you're allowing the function to mutably borrow the data until 'a ends, thus locking yourself out of ever being able to touch the data again.
It smells like you're trying to create a single struct which has one field which borrows from another of its fields. This essentially is not something you're allowed to do; borrowing must be well structured as a directed graph.
But given the example construction of the Pwm doesn't capture 'a in any way, you probably want Pwm<'static>. Many libraries will use Ty<'a> as the borrowed type and Ty<'static> as the owning type (using something like Cow underneath), to avoid needing separate owning and nonowning types.
The one exception: when both lifetimes are elided, then it has more correct applications. ↩︎
I'm basically saying the same thing as @CAD97 with different words in this comment.
Until the end of the validity of the struct anyway. But yes, that's the problem with &'a mut self; it exclusively borrows self "forever".
You haven't included the signature of function. But at a guess, it's trying to borrow from the self.current_setting value, and you're trying to assign that borrow back to self.pwm. If so, there's no safe way to do that without running into the borrowed-forever problem. (It's also extremely hard to do unsafely without being unsound.)
Thank you. I understand the problem better now. The issue is with the library I am trying to use. The struct starts with
pub struct PasswordMaker<'a, T : HasherList>{
username : &'a str,
It does not take ownership and I have to provide a long lived reference. So my problem is to tell the compiler that my String as the source for &str will be available long enough. It should be as both the string and Pwm<'a> are both in the same struct but &str can be quite tricky.
You're may be confusing the liveness of the String value or of the containing struct (i.e. from creation to destruction) as a "lifetime". While common nomenclature in general, that's not what a Rust lifetime (one of those '_ things) is. They're more a (compile-time) tool to track borrows to avoid a lot of memory safety issues like aliased mutation (data races) and dangling references, etc.
If you made it self-referential and then moved the Example<'_>, the current_pid field would dangle because all the values in the pids field moved too. (Rust has no move constructors.)
It doesn't matter to this example that the pids haven't been destructed after the move.
There's no way for the borrow checker to differentiate this case from the String case, which is one reason (but not the only reason) why "straight-forward" self-referential structs aren't safely possible in a useful way.
So it is impossible to use the struct with the references as a field in my struct because i cannot provide a source for the reference with sufficient lifetime. So I could create the struct every time I need it and throw it away afterwards or change the &str references to String because sometimes you just have to make a copy.