Support unsized coercions for `Lazy` type.
EFanZh opened this issue · 2 comments
Currently, the following code does not compile:
use once_cell::sync::Lazy;
use std::sync::Arc;
fn foo() {
let x: Arc<Lazy<[i32; 3]>> = Arc::new(Lazy::new(|| [2, 3, 4]));
let y: Arc<Lazy<[i32]>> = x;
}
Is it possible for Lazy
to support unsized coercions like types like RefCell
? For example, with RefCell
, I can do this:
use std::cell::RefCell;
use std::sync::Arc;
fn foo() {
let x: Arc<RefCell<[i32; 3]>> = Arc::new(RefCell::new([2, 3, 4]));
let y: Arc<RefCell<[i32]>> = x;
}
What a delightful nerdy issue, thanks!
Yeah, I think that should be possible with some work. I think (haven't checked) that the reason why it doesn't work today is because we ultimately store an Option
. Using MaybeUninit
and a bool flag might help here!
Now I start to think it might not be possible. The problem is that Lazy
has another generic argument F
which should be a FnOnce
type. So the sized Lazy
type could be:
Lazy<[i32; 3], impl FnOnce() -> [i32; 3]>
And the unsized Lazy
type would be
Lazy<[i32], impl FnOnce() -> [i32]>
I have not idea how the conversion would work. If it is not possible for Lazy
, how about OnceCell
?