Trouble with mutability of traits with lifetime

Hi, I got the error cannot borrow X as mutable more than once at a time using this playground code which utilizes traits, lifetimes and mutability. I tried everything, but can't find a solution.

It looks like I need to think over the concept of my program again, but maybe there is an actual solution to this issue.

Anyways, thanks for any help :smile:

You'll need different lifetimes. This will solve some of the errors:

pub fn handle_widget<'a>(
    ta: &'a mut Box<dyn TraitA<'a> + 'a>,
    tb: &'a mut Box<dyn TraitB<'a> + 'a>,
    smth: &'a mut Something<'a>,
) {
    ta.foo(tb, smth);

    for child in ta.bar() {
        handle_widget(child, tb, smth);
    }
}

pub trait TraitA<'a> {
    fn foo(&self, tb: &'a mut Box<dyn TraitB<'a> + 'a>, foo: &'a mut Something);
    fn bar(&mut self) -> &mut Vec<Box<dyn TraitA<'a> + 'a>>;
}

trait TraitB<'a> {}

struct Something<'a>(&'a str);

The problem is that you are using the same lifetime everywhere, thus requiring all of them to be the same. In practice however you don't always want lifetimes to be the same, actually most of the time you want to allow them to be different, otherwise one would be overconstrained due to appearing in another type.

It's unclear from your "simplified" example how the trait will be used, so it's hard to tell which lifetimes actually need to be equal and which can be different. I would suggest starting with all lifetimes being different and only later make them equal if you notice that they need to be.

3 Likes

Your code is the same as mine. Did you paste the right snippet?

In particular, you never want &'a mut SomethingElseInvolving<'a>. If you think you need it, you might be attempting some other antipattern.

2 Likes

Sorry, I might have copied the wrong tab and I can't find it anymore. But it basically demonstrated what @SkiFire13 said.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.