LazyLock/Cell get_mut() and DerefMut · Issue #429 · rust-lang/libs-team (original) (raw)

Proposal

Problem statement

When porting rust-analyzer once_cell code to use std's lazy types, one place used &mut LazyCell<T> and wanted to get a &mut T from it (initializing if not initialized yet). once_cell provides DerefMut and get_mut() for that on its Lazy types, but std has no way to mutably access the contents of a LazyLock/Cell.

Motivating examples or use cases

The code I ported is here: https://github.com/rust-lang/rust-analyzer/blob/91aa3f46b32032d7d62c4e94e4ea973f63aacc8f/crates/hir-def/src/generics.rs#L600

That code could use Option (this is what I transformed it into), but that means having to carry around the initializer every time. Alternatively, there could be a LazyMut type, but the role seems to fit LazyCell/Lock perfectly and there is even no need for perf compromises. Also, even though I don't have a use-case for that, maybe someone need to access a Lazy sometimes mutably and sometimes immutably.

Solution sketch

/// There is no need for locking or reentrancy handling; this can be as simple as a function call. impl DerefMut for LazyCell { ... } impl LazyCell { pub fn get_mut(this: &mut Self) -> Option<&mut T>; }

impl DerefMut for LazyLock { ... } impl LazyLock { pub fn get_mut(this: &mut Self) -> Option<&mut T>; }

Alternatives

We can provide only get_mut() or only DerefMut. I choose to provide both because DerefMut is easier to work with, but get_mut() is a standard in interior mutable types.

This could be emulated using Option, as I said.

https://docs.rs/once_cell/latest/once_cell/sync/struct.Lazy.html#method.get_mut
https://docs.rs/once_cell/latest/once_cell/sync/struct.Lazy.html#impl-DerefMut-for-Lazy%3CT,+F%3E
https://docs.rs/once_cell/latest/once_cell/unsync/struct.Lazy.html#method.get_mut
https://docs.rs/once_cell/latest/once_cell/unsync/struct.Lazy.html#impl-DerefMut-for-Lazy%3CT,+F%3E

What happens now?

This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

Second, if there's a concrete solution: