RFC idea: pub(const)


#1

Today I came up with an idea for Rust’s struct and tuple field visibilities.
Even though there is an RFC expanding the expression possibilities of pub by pub(restricted) I am still finding myself in a position where I want my struct fields to be visible from the outside but without mutability.

To give an example:

struct Foo { pub bar: Bar }

Here I want Foo's bar field to be visible from the outside but it should be only mutable from inner accesses.
With the default pub keyword this is not possible and so I need to make the following work around:

struct Foo { bar: Bar }

impl Foo {
    pub fn get_bar(&self) -> &Bar {
        &self.bar
    }
}

Obviously this getter method works but has a downside besides being boilerplate code which is connected to the borrow checker since using get_bar requires a borrow of self within a method while a simple access of self.bar does not result in a borrow of self.

My proposal would be something similar to this:

struct Foo { pub(const) bar: Bar }

This allows default access capabilities from the inside of Foo but restricts to immutable access from the outside.

What do you think about this?
Is it feasable or has this proposal some unseen downsides?


#2

Seems nice.

I’ve also ran into issue of borrowing whole object just to lend a single field back. Would it be feasible to fix that problem, too? This is especially getting in the way with mutable borrows.

pub fn get_bar_mut(&mut self) -> &'self.bar mut Bar  {
    &mut self.bar
}

#3

I think future rework of the borrow checking includes finer grained borrowing, so the getter may be enough in the future.


#4

I think you’re referring to non-lexical lifetimes, but that won’t help if you’re hoping to have values from get_foo_mut() and get_bar_mut() usable at the same time. Whereas it is possible to simultaneously borrow &mut s.foo and &mut s.bar if you have field access.


#5

Mmm not specifically non-lexical lifetimes, but it could be my memories are wrong. It should be possible to track borrows in a more fined grained manner with functions that return a borrow of a field though.