Generic mutability parameters


I meant that your approach requires the code in the body to be the same and only mutability is “forwarded” - that’s essentially a trivial function. The example was a case where the code should differ but only slightly based on mutability. This is not a trivial case but your proposal doesn’t work for it (the fact you can work around with unwrap_or in this particular case doesn’t generalize).

They don’t cause a conflict. It would limit the type of code you can write in the fn body. In the immutable case the code can stick a 'static; in the mutable they may not. It’s just an example of an extra restriction on the code.

But maybe that’s fine as what you’re suggesting is mutability forwarding or “passthrough” mutability. I’m not sure I’d consider it abstraction, at least in the same sense as AsRef/AsMut/Borrow/BorrowMut but perhaps exact nomenclature is unimportant.


I wonder how much of this can be implemented with associated type constructors and the family pattern:

trait RefFamily {
  type<'a, T> Ref : Deref<Target=T>;

struct ShrRef;
impl RefFamily for ShrRef {
  type<'a, T> Ref = &'a T;

struct MutRef;
impl RefFamily for MutRef {
  type<'a, T> Ref = &'a mut T;

struct Foo(i32, ...);
impl Foo {
  fn accessor<T: RefFamily>(self: T::Ref<Self>) -> T::Ref<i32>

So, we can write down the type of these accessors using associated type constructors. But we can probably not implement the accessors safely. But maybe with something like DerefField, that would be possible?


True, I hadn’t considered this. A mutably-generic collection would also be unable to interact with other always-immutable arguments to the function. Previously, I was thinking any immutable-only function body would work, but now I can see that’s not that case. :slight_smile:

Still, I think it could be worthwhile, obviously just for the cases which still work given this restriction.

Maybe that’s not the right word then. Certainly, being able to pass-through mutability is the goal here, whatever that’s called.

This is interesting. Not as neat as syntax-level support, but would be even more versatile. It’s kind of a shame we already have so many FooRef/FooMut-type trait pairs… although maybe you could unify such pairs, as needed, using a similar family pattern?