More inference-friendly API for lazy
The signature for new was ``` fn new<F>(f: F) -> Lazy<T, F> ``` Notably, with `F` unconstrained, `T` can be literally anything, and just `let _ = Lazy::new(|| 92)` would not typecheck. This historiacally was a necessity -- `new` is a `const` function, it couldn't have any bounds. Today though, we can move `new` under the `F: FnOnce() -> T` bound, which gives the compiler enough data to infer the type of T from closure.
This commit is contained in:
parent
33b55ac39f
commit
3cddc8bff6
@ -31,7 +31,7 @@ pub struct LazyCell<T, F = fn() -> T> {
|
|||||||
init: Cell<Option<F>>,
|
init: Cell<Option<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F> LazyCell<T, F> {
|
impl<T, F: FnOnce() -> T> LazyCell<T, F> {
|
||||||
/// Creates a new lazy value with the given initializing function.
|
/// Creates a new lazy value with the given initializing function.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -51,9 +51,7 @@ impl<T, F> LazyCell<T, F> {
|
|||||||
pub const fn new(init: F) -> LazyCell<T, F> {
|
pub const fn new(init: F) -> LazyCell<T, F> {
|
||||||
LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
|
LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F: FnOnce() -> T> LazyCell<T, F> {
|
|
||||||
/// Forces the evaluation of this lazy value and returns a reference to
|
/// Forces the evaluation of this lazy value and returns a reference to
|
||||||
/// the result.
|
/// the result.
|
||||||
///
|
///
|
||||||
|
@ -106,6 +106,12 @@ fn lazy_new() {
|
|||||||
assert_eq!(called.get(), 1);
|
assert_eq!(called.get(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that we can infer `T` from closure's type.
|
||||||
|
#[test]
|
||||||
|
fn lazy_type_inference() {
|
||||||
|
let _ = LazyCell::new(|| ());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn aliasing_in_get() {
|
fn aliasing_in_get() {
|
||||||
let x = OnceCell::new();
|
let x = OnceCell::new();
|
||||||
|
@ -44,17 +44,14 @@ pub struct LazyLock<T, F = fn() -> T> {
|
|||||||
cell: OnceLock<T>,
|
cell: OnceLock<T>,
|
||||||
init: Cell<Option<F>>,
|
init: Cell<Option<F>>,
|
||||||
}
|
}
|
||||||
|
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
||||||
impl<T, F> LazyLock<T, F> {
|
|
||||||
/// Creates a new lazy value with the given initializing
|
/// Creates a new lazy value with the given initializing
|
||||||
/// function.
|
/// function.
|
||||||
#[unstable(feature = "once_cell", issue = "74465")]
|
#[unstable(feature = "once_cell", issue = "74465")]
|
||||||
pub const fn new(f: F) -> LazyLock<T, F> {
|
pub const fn new(f: F) -> LazyLock<T, F> {
|
||||||
LazyLock { cell: OnceLock::new(), init: Cell::new(Some(f)) }
|
LazyLock { cell: OnceLock::new(), init: Cell::new(Some(f)) }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
|
||||||
/// Forces the evaluation of this lazy value and
|
/// Forces the evaluation of this lazy value and
|
||||||
/// returns a reference to result. This is equivalent
|
/// returns a reference to result. This is equivalent
|
||||||
/// to the `Deref` impl, but is explicit.
|
/// to the `Deref` impl, but is explicit.
|
||||||
|
@ -136,6 +136,12 @@ fn sync_lazy_poisoning() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that we can infer `T` from closure's type.
|
||||||
|
#[test]
|
||||||
|
fn lazy_type_inference() {
|
||||||
|
let _ = LazyCell::new(|| ());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_sync_send() {
|
fn is_sync_send() {
|
||||||
fn assert_traits<T: Send + Sync>() {}
|
fn assert_traits<T: Send + Sync>() {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user