diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2022-10-29 09:56:20 +0100 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2022-10-29 09:56:20 +0100 |
| commit | 3cddc8bff6d5357fc68a87c802a7f4fa3e1642a7 (patch) | |
| tree | 4203b0d74735994646d293cf245516d8ad7cc4de | |
| parent | 33b55ac39fa633d0983fad014469e1036669bf28 (diff) | |
| download | rust-3cddc8bff6d5357fc68a87c802a7f4fa3e1642a7.tar.gz rust-3cddc8bff6d5357fc68a87c802a7f4fa3e1642a7.zip | |
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.
| -rw-r--r-- | library/core/src/cell/lazy.rs | 4 | ||||
| -rw-r--r-- | library/core/tests/lazy.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sync/lazy_lock.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sync/lazy_lock/tests.rs | 6 |
4 files changed, 14 insertions, 7 deletions
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 7844be5f783..39209772c4e 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -31,7 +31,7 @@ pub struct LazyCell<T, F = fn() -> T> { 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. /// /// # Examples @@ -51,9 +51,7 @@ impl<T, F> LazyCell<T, F> { pub const fn new(init: F) -> LazyCell<T, F> { 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 /// the result. /// diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs index 70fcc6d2d4b..c7c3c479b71 100644 --- a/library/core/tests/lazy.rs +++ b/library/core/tests/lazy.rs @@ -106,6 +106,12 @@ fn lazy_new() { assert_eq!(called.get(), 1); } +// Check that we can infer `T` from closure's type. +#[test] +fn lazy_type_inference() { + let _ = LazyCell::new(|| ()); +} + #[test] fn aliasing_in_get() { let x = OnceCell::new(); diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 535cc1c42fc..4955975ebde 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -44,17 +44,14 @@ pub struct LazyLock<T, F = fn() -> T> { cell: OnceLock<T>, init: Cell<Option<F>>, } - -impl<T, F> LazyLock<T, F> { +impl<T, F: FnOnce() -> T> LazyLock<T, F> { /// Creates a new lazy value with the given initializing /// function. #[unstable(feature = "once_cell", issue = "74465")] pub const fn new(f: F) -> LazyLock<T, 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 /// returns a reference to result. This is equivalent /// to the `Deref` impl, but is explicit. diff --git a/library/std/src/sync/lazy_lock/tests.rs b/library/std/src/sync/lazy_lock/tests.rs index f11b66bfca5..a5d4e25c596 100644 --- a/library/std/src/sync/lazy_lock/tests.rs +++ b/library/std/src/sync/lazy_lock/tests.rs @@ -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] fn is_sync_send() { fn assert_traits<T: Send + Sync>() {} |
