Is there a wrapper type that blocks mut without requiring allocation?

⚓ Rust    📅 2025-08-28    👤 surdeus    👁️ 3      

surdeus

Say I have this type, and it's working fine:

struct Task {
    status: Rc<Mutex<TaskState>>,
    db: DatabaseClient,
    foo: Foo,
    ...
}

In my program, the Task is always the last owner of status and therefore always takes care of cleanup. For performance, I now want to eliminate the reference counting, i.e. remove the Rc and store the Mutex directly inside the Task. Other code can still have short-lived shared references to the Mutex.

Now the problem. The existing code sometimes uses &mut Task. This works fine with Rc because the Rc means that a mut reference to the Task does not imply exclusive access to the Mutex<TaskState>. Mut access isn't transitive through an Rc; the Rc blocks it. But if I remove the Rc, I can't have a &mut Task while other references to the mutex exist.

If I'm reading the UnsafeCell docs correctly, they explicitly say that it doesn't do this ("neither the cell nor the wrapped value may be aliased for the duration of that &mut borrow"). Is there anything in Rust that does, even with unsafe code?

(Of course there are plenty of ways I could do a bigger refactor, maybe take a slight perf hit, and not need this capability. But I'm interested in the capability.)

3 posts - 2 participants

Read full topic

🏷️ Rust_feed