[Pre-RFC] Unify references and make them generic over mutability

Is there a use case (and if so, a mechanism) for inverted mutability? Let's say I have two parameters, exactly one of which can be mut. Is there a way to use this to have def f(a: &mut T1, b: &T2) and def f(a: &T1, b: &mut T2) using a single mut generic parameter (e.g., def f<mut M>(a: &M T1, b: &!M T2)?

Like I said, no idea if there's a concrete use cases at the moment, but flipping, "upgrading", "downgrading", and possibly even combining operators on these mutability may be useful in some places.

Is there anything especially useful to take away from this? I'm asking for people who haven't been following C++ developments very closely.

There seem to be a whole lot more cases for C++ though. Though this also gave me another idea:

Why should this be restricted to references only? So additionally to

let mut foo = Foo::new();
foo.get::<const>();
foo.get::<mut>();

we could also have

let ptr = (&mut foo) as *mut Foo;
unsafe {
    Foo::get::<*const>(ptr);
    Foo::get::<*mut>(ptr);
}

This could become a better and more general alternative to addr_of! and addr_of_mut! with some added benefits. And the compiler would still guarantee to emit one single function for all of those calls (if they aren't getting inlined, that is).

It's something to think about and needs a bit more considering.

  • What would be the exact requirements for the pointers being passed be to not cause UB? I guess it would be kinda similar to implementing the same operations using addr_of! and addr_of_mut!.
  • It would also be useful to just provide <const> and <*const> or respectively <mut> and <*mut>. How would the syntax deal with those cases?

The main use-case for this feature would be some kinda of access to data like indexing something like a vector, accessing a field or an iterator over a set of values or anything similar.

I can imagine cases where it might be useful to provide two separate mutability arguments.

This would similar to that, but with added constraints between them.

I could vaguely imagine a case where you could say "If A is shared then B has to be shared as well", and "If A is mutable then B has to be mutable", though I cannot think of a good use case for that either.

But "A and B must have different mutability" seems very odd though and I can't think of a data structure that would require that.

So I don't know, let's not consider such weird things unless someone comes up with an example where this is useful.

I finally published my implementation. It works, but lacks syntax/macro support. It's on GitHub.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.