Skip to content

Commit 4b668a1

Browse files
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.
2 parents db79625 + 3cddc8b commit 4b668a1

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

library/core/src/cell/lazy.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub struct LazyCell<T, F = fn() -> T> {
3535
init: Cell<Option<F>>,
3636
}
3737

38-
impl<T, F> LazyCell<T, F> {
38+
impl<T, F: FnOnce() -> T> LazyCell<T, F> {
3939
/// Creates a new lazy value with the given initializing function.
4040
///
4141
/// # Examples
@@ -55,9 +55,7 @@ impl<T, F> LazyCell<T, F> {
5555
pub const fn new(init: F) -> LazyCell<T, F> {
5656
LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
5757
}
58-
}
5958

60-
impl<T, F: FnOnce() -> T> LazyCell<T, F> {
6159
/// Forces the evaluation of this lazy value and returns a reference to
6260
/// the result.
6361
///

library/core/tests/lazy.rs

+6
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ fn lazy_new() {
106106
assert_eq!(called.get(), 1);
107107
}
108108

109+
// Check that we can infer `T` from closure's type.
110+
#[test]
111+
fn lazy_type_inference() {
112+
let _ = LazyCell::new(|| ());
113+
}
114+
109115
#[test]
110116
fn aliasing_in_get() {
111117
let x = OnceCell::new();

library/std/src/sync/lazy_lock.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,14 @@ pub struct LazyLock<T, F = fn() -> T> {
4646
cell: OnceLock<T>,
4747
init: Cell<Option<F>>,
4848
}
49-
50-
impl<T, F> LazyLock<T, F> {
49+
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
5150
/// Creates a new lazy value with the given initializing
5251
/// function.
5352
#[unstable(feature = "once_cell", issue = "74465")]
5453
pub const fn new(f: F) -> LazyLock<T, F> {
5554
LazyLock { cell: OnceLock::new(), init: Cell::new(Some(f)) }
5655
}
57-
}
5856

59-
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
6057
/// Forces the evaluation of this lazy value and
6158
/// returns a reference to result. This is equivalent
6259
/// to the `Deref` impl, but is explicit.

library/std/src/sync/lazy_lock/tests.rs

+6
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ fn sync_lazy_poisoning() {
136136
}
137137
}
138138

139+
// Check that we can infer `T` from closure's type.
140+
#[test]
141+
fn lazy_type_inference() {
142+
let _ = LazyCell::new(|| ());
143+
}
144+
139145
#[test]
140146
fn is_sync_send() {
141147
fn assert_traits<T: Send + Sync>() {}

0 commit comments

Comments
 (0)