Fields in Traits

I don't think this is true in the existing proposal, but I think it arises in the "views" variant i've been talking about. That is, in the existing proposal, the disjointness requirement isn't something we have to check in "client code" -- rather, we check when you define the impl that all the disjointness conditions are met.

But there are some borrow checker interactions that weren't cleared defined in the RFC. For example, would accessing a trait field a be considered to overlap with a struct field b, presuming that b is not mapped to a? I had actually assumed it would be, and hence this code would error:

trait Foo {
    let a: u32
}

struct Bar {
    b: u32,
    a2: u32,
}

impl Foo for Bar {
    let a = self.a2;
}

fn main() {
    let mut bar = Bar { ... };
    let p = &mut bar.b;
    let q = &mut bar.a; // where `a` is defined in the trait
}

Put another way, the borrow checker here sees two paths, where I've written the field names with "fully qualified paths" telling you where they came from:

bar.(Bar::b) // inherent field of `Bar`
bar.(Foo::a) // field defined in trait `Foo`

My assumption was that we would consider two inherent fields (e.g., b and a2) to be disjoint if they come from the same struct. We would also consider two trait fields to be disjoint if they come from the same trait (or supertrait/subtrait relationship). But fields from two unrelated traits would be considered to maybe overlap -- and the same for a field from some trait and some struct.

But I guess we can imagine the borrow checker "seeing through" the borrow of a to understand that it really maps to a2 and hence is disjoint from b. In that case, we do want to think about privacy/encapsulation.

And certainly this comes up in the views concept I was kicking around.

1 Like