diff options
| author | Michael Goulet <michael@errs.io> | 2022-12-27 12:33:33 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-27 12:33:33 -0800 |
| commit | 4b668a1feed45b3061fbf0d1d42fb1a695c0d4b3 (patch) | |
| tree | 68ccf98bcfa2d79d78ae0fbe27a4a505a056b1c2 | |
| parent | db7962532610cfbfb9be17e8d6c1b48acf5ed184 (diff) | |
| parent | 3cddc8bff6d5357fc68a87c802a7f4fa3e1642a7 (diff) | |
| download | rust-4b668a1feed45b3061fbf0d1d42fb1a695c0d4b3.tar.gz rust-4b668a1feed45b3061fbf0d1d42fb1a695c0d4b3.zip | |
Rollup merge of #103718 - matklad:infer-lazy, r=dtolnay
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 b355d94ce49..19f80daef1d 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -35,7 +35,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 @@ -55,9 +55,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 c8d3289ca4a..bf5a716fa03 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -46,17 +46,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>() {} |
