Having mutability in several views of a struct

Hmm, so let me bring in a bit more context. The main time that I think this problem strikes people is sort of mundane:

pub struct MyStruct {
    some_data: Data,
    some_more_data: MoreData,
}

impl MyStruct {
    pub fn some_function(&mut self) {
        let ref1 = self.ref_to_some_data(); // borrows self
        self.modify_some_more_data(ref1); // error, self is still borrowed
    }

    fn ref_to_some_data(&self) -> &u32 {
        &self.some_data.some_field
    }

    fn modify_some_more_data(&mut self, ref: &u32) {
        self.some_more_data.modify(ref)
    }
}

Here the key point is that ref_to_some_data and modify_some_more_data access disjoint fields. (As I wrote earlier, I would like code this to “just compile” – with no syntactic changes – but let’s discuss that a bit later and focus instead on how you would write out something more explicit if you wanted to.)

I was thinking that maybe “views” might be that you get into via coercions or casts. Basically a &mut Foo could be coerced to a &mut FooView, where FooView is some view on Foo that selects a subset of its fields. Similarly, borrows like &mut foo would have not only a lifetime 'a of the borrow, but a view V that is being borrowed, so that the final type is &'a mut V.

(Note that we don’t presently allow you to write the lifetime of a borrow explicitly; we probably wouldn’t let you write the lifetime of a view either, but instead use context, meaning you might do something like this to select a view explicitly:

let x: &mut View = &mut foo
(&mut foo) as &mut View

Most of the time, though, I imagine you’d be getting your view via the self type of a method that is being called:

fn foo(self: &mut View, ...) { ... }

and when we insert the “autoref” for x.foo(), we would insert one with the appropriate view.

3 Likes