Ok, I still think that shareable is a better name, moving out of a field is not significantly different from just reading the value of the field (via something like std::ptr::read), and then forgetting the old value. So, I think that it is fine to extend the notion of shareable in this way. Yes, this differs from shared references, but this difference is less egregious than calling it read-only. Especially, when there is a whole class of types which are an exception to the read-only rule. I can't think of any way to cause a bug by moving out of a field, but I have already shown that it is easy to cause bugs because you were thinking in terms of mutability, via things like atomics.
tldr: I think calling it read-only will lead to far more bugs than calling it shareable
Possibly "fetch-only" may be less prone to the assumptions surrounding "read only", because once you fetch a thing, it doesn't indicate you can't modify it. ( And the inverse would be 'store-only' ).
Mostly these 2 terms to me indicate properties of the unit the field is on, not the properties of the field itself.
It's interesting that Rust doesn't seem to have an existing name for the "porous immutability" situation of &. Shared is the other aspect of it.
Perhaps "Non-writeable fields" is less imprecise than read-only, but I don't really mind either. As long as relationship with & is clear, Rust programmers will know what this allows.
Since we bikeshed only about the name I take as a good sign that the core functionality is uncontroversial.
Fields, this evaluates the subexpression in a mutable place expression context.
It is something like "... when a field is not read-only on the module containing the expression".
... except:
This restriction is not covered by the sentence above because the struct construction is not using the "place" concept.
I want to argue that struct initialization restriction is not really necessary, partly for the theoretical simplicity.
If a struct should maintain certain invariant on field values, its constructor shouldn't be public. An issue is that this way cannot be practiced naturally in the current stable Rust. A struct constructor automatically becomes public if and only if all fields are public. Probably #[non_exhaustive] is the answer (already on beta).
The idea was that if a field is pub(&), it should be impossible to assign directly to it outside of the module. This means that initializing the struct must be forbidden, if not all fields are fully visible. Having a macro (e.g. #[non_exhaustive]) for this is error-prone, since you could forget to add it.
#[non_exhaustive] has a slightly different purpose. EDIT: I was wrong.
I agree. Being able to move/destructure the field is an important part of the feature; however, I think it's more important that the syntax reflects that the field can't be borrowed as &mut.
When someone sees the pub(&) syntax for the first time and wrongly assumes that the field can't be destructured, this probably won't cause any bugs, so it's not too much of a problem.
I should mention that I stole this idea from @kornel who proposed the idea and @RustyYato and @CAD97, who came up with the syntax.
My personal view is that there isn't a pressing need here for integrating &mut T vs. &T into the module system because:
The situations in which this is needed are restricted to when you have exposed a field as pub and have ownership (but haven't made all fields pub / the type implements Drop -- otherwise you can move out, mutate, and re-construct again) or you have &mut. It's not all that often this happens in my experience.
This can be achieved through other means, for example, you can use:
and then use ReadOnly<T> for the fields you want to restrict mutable borrows of.
It's true that this approach does not allow for destructuring and pattern matching, but then this could also be solved with DerefPure (desirable for other reasons). At any rate, I think adding additional requirements like pattern matching atop the existing ones makes this increasingly niche.
(We can also make this truly immutable and exclude interior mutability if we also expose the Freeze auto trait in a stable fashion.)
Beyond this, I think that we already have a long backlog of features to implement. The proposed feature seems like it would touch many places in the compiler and would be non-trivial to implement. Therefore, I think that in the medium term, we should focus our limited resources on the existing backlog.
Thanks a lot for the valuable insights! I'm unfamiliar with the inner workings of the compiler, so I didn't know if it would be hard to implement. I understand that other features have a higher priority. If others think so as well, I'd be okay to postpone the RFC.