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.
Links and related work
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):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.