Skip to content

Commit

Permalink
Unrolled build for rust-lang#121377
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#121377 - pitaj:lazy_cell_fn_pointer, r=dtolnay

Stabilize `LazyCell` and `LazyLock`

Closes rust-lang#109736

This stabilizes the [`LazyLock`](https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html) and [`LazyCell`](https://doc.rust-lang.org/stable/std/cell/struct.LazyCell.html) types:

```rust
static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
    println!("initializing");
    let mut m = HashMap::new();
    m.insert(13, "Spica".to_string());
    m.insert(74, "Hoyten".to_string());
    m
});

let lazy: LazyCell<i32> = LazyCell::new(|| {
    println!("initializing");
    92
});
```

r? libs-api
  • Loading branch information
rust-timer committed May 26, 2024
2 parents 1ba35e9 + 4913ab8 commit f3b13b3
Show file tree
Hide file tree
Showing 34 changed files with 60 additions and 82 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}

if let ConstContext::Static(_) = ccx.const_kind() {
err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell");
err.note("consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`");
}

err
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#![feature(extend_one)]
#![feature(hash_raw_entry)]
#![feature(hasher_prefixfree_extras)]
#![feature(lazy_cell)]
#![feature(lint_reasons)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![feature(lazy_cell)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
#![allow(internal_features)]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#![allow(internal_features)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![feature(lazy_cell)]

mod accepted;
mod builtin_attrs;
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ This API is completely unstable and subject to change.
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(lazy_cell)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(decl_macro)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(thread_spawn_unchecked)]
#![feature(try_blocks)]
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,10 +1316,8 @@ declare_lint! {
/// * If you are trying to perform a one-time initialization of a global:
/// * If the value can be computed at compile-time, consider using
/// const-compatible values (see [Constant Evaluation]).
/// * For more complex single-initialization cases, consider using a
/// third-party crate, such as [`lazy_static`] or [`once_cell`].
/// * If you are using the [nightly channel], consider the new
/// [`lazy`] module in the standard library.
/// * For more complex single-initialization cases, consider using
/// [`std::sync::LazyLock`].
/// * If you truly need a mutable global, consider using a [`static`],
/// which has a variety of options:
/// * Simple data types can be directly defined and mutated with an
Expand All @@ -1334,9 +1332,7 @@ declare_lint! {
/// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html
/// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html
/// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics
/// [`lazy`]: https://doc.rust-lang.org/nightly/std/lazy/index.html
/// [`lazy_static`]: https://crates.io/crates/lazy_static
/// [`once_cell`]: https://crates.io/crates/once_cell
/// [`std::sync::LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html
/// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html
/// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
pub CONST_ITEM_MUTATION,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_session/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(let_chains)]
#![feature(lazy_cell)]
#![feature(option_get_or_insert_default)]
#![feature(rustc_attrs)]
#![feature(map_many_mut)]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ use crate::ptr::{self, NonNull};
mod lazy;
mod once;

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub use lazy::LazyCell;
#[stable(feature = "once_cell", since = "1.70.0")]
pub use once::OnceCell;
Expand Down
20 changes: 7 additions & 13 deletions library/core/src/cell/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ enum State<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::cell::LazyCell;
///
/// let lazy: LazyCell<i32> = LazyCell::new(|| {
Expand All @@ -36,7 +34,7 @@ enum State<T, F> {
/// // 92
/// // 92
/// ```
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub struct LazyCell<T, F = fn() -> T> {
state: UnsafeCell<State<T, F>>,
}
Expand All @@ -47,8 +45,6 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::cell::LazyCell;
///
/// let hello = "Hello, World!".to_string();
Expand All @@ -58,7 +54,8 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
/// assert_eq!(&*lazy, "HELLO, WORLD!");
/// ```
#[inline]
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(f: F) -> LazyCell<T, F> {
LazyCell { state: UnsafeCell::new(State::Uninit(f)) }
}
Expand All @@ -70,7 +67,6 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
/// #![feature(lazy_cell_consume)]
///
/// use std::cell::LazyCell;
Expand Down Expand Up @@ -99,8 +95,6 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::cell::LazyCell;
///
/// let lazy = LazyCell::new(|| 92);
Expand All @@ -109,7 +103,7 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
/// assert_eq!(&*lazy, &92);
/// ```
#[inline]
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub fn force(this: &LazyCell<T, F>) -> &T {
// SAFETY:
// This invalidates any mutable references to the data. The resulting
Expand Down Expand Up @@ -173,7 +167,7 @@ impl<T, F> LazyCell<T, F> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
type Target = T;
#[inline]
Expand All @@ -182,7 +176,7 @@ impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: Default> Default for LazyCell<T> {
/// Creates a new lazy value using `Default` as the initializing function.
#[inline]
Expand All @@ -191,7 +185,7 @@ impl<T: Default> Default for LazyCell<T> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_tuple("LazyCell");
Expand Down
1 change: 0 additions & 1 deletion library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@
#![feature(pointer_is_aligned_to)]
#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(lazy_cell)]
#![feature(unsized_tuple_coercion)]
#![feature(const_option)]
#![feature(const_option_ext)]
Expand Down
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,6 @@
#![feature(edition_panic)]
#![feature(format_args_nl)]
#![feature(get_many_mut)]
#![feature(lazy_cell)]
#![feature(log_syntax)]
#![feature(test)]
#![feature(trace_macros)]
Expand Down
41 changes: 23 additions & 18 deletions library/std/src/sync/lazy_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ union Data<T, F> {
/// Initialize static variables with `LazyLock`.
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::collections::HashMap;
///
/// use std::sync::LazyLock;
Expand Down Expand Up @@ -61,8 +59,6 @@ union Data<T, F> {
/// ```
/// Initialize fields with `LazyLock`.
/// ```
/// #![feature(lazy_cell)]
///
/// use std::sync::LazyLock;
///
/// #[derive(Debug)]
Expand All @@ -76,17 +72,29 @@ union Data<T, F> {
/// println!("{}", *data.number);
/// }
/// ```

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub struct LazyLock<T, F = fn() -> T> {
once: Once,
data: UnsafeCell<Data<T, F>>,
}

impl<T, F: FnOnce() -> T> LazyLock<T, F> {
/// Creates a new lazy value with the given initializing function.
///
/// # Examples
///
/// ```
/// use std::sync::LazyLock;
///
/// let hello = "Hello, World!".to_string();
///
/// let lazy = LazyLock::new(|| hello.to_uppercase());
///
/// assert_eq!(&*lazy, "HELLO, WORLD!");
/// ```
#[inline]
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(f: F) -> LazyLock<T, F> {
LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
}
Expand All @@ -107,7 +115,6 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
/// #![feature(lazy_cell_consume)]
///
/// use std::sync::LazyLock;
Expand Down Expand Up @@ -145,8 +152,6 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
/// # Examples
///
/// ```
/// #![feature(lazy_cell)]
///
/// use std::sync::LazyLock;
///
/// let lazy = LazyLock::new(|| 92);
Expand All @@ -155,7 +160,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
/// assert_eq!(&*lazy, &92);
/// ```
#[inline]
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub fn force(this: &LazyLock<T, F>) -> &T {
this.once.call_once(|| {
// SAFETY: `call_once` only runs this closure once, ever.
Expand Down Expand Up @@ -191,7 +196,7 @@ impl<T, F> LazyLock<T, F> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T, F> Drop for LazyLock<T, F> {
fn drop(&mut self) {
match self.once.state() {
Expand All @@ -204,7 +209,7 @@ impl<T, F> Drop for LazyLock<T, F> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
type Target = T;

Expand All @@ -219,7 +224,7 @@ impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: Default> Default for LazyLock<T> {
/// Creates a new lazy value using `Default` as the initializing function.
#[inline]
Expand All @@ -228,7 +233,7 @@ impl<T: Default> Default for LazyLock<T> {
}
}

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_tuple("LazyLock");
Expand All @@ -242,13 +247,13 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {

// We never create a `&F` from a `&LazyLock<T, F>` so it is fine
// to not impl `Sync` for `F`.
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
// auto-derived `Send` impl is OK.

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: RefUnwindSafe + UnwindSafe, F: UnwindSafe> RefUnwindSafe for LazyLock<T, F> {}
#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl<T: UnwindSafe, F: UnwindSafe> UnwindSafe for LazyLock<T, F> {}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};

#[unstable(feature = "lazy_cell", issue = "109736")]
#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub use self::lazy_lock::LazyLock;
#[stable(feature = "once_cell", since = "1.70.0")]
pub use self::once_lock::OnceLock;
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(round_char_boundary)]
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_dev/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(rustc_private)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#![allow(rustc::untranslatable_diagnostic)]
#![feature(rustc_private)]
#![feature(let_chains)]
#![feature(lazy_cell)]
#![feature(lint_reasons)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/compile-test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(lazy_cell)]
#![feature(is_sorted)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/dogfood.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//!
//! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context

#![feature(lazy_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]

Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/lint_message_convention.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(lazy_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]

Expand Down
2 changes: 0 additions & 2 deletions src/tools/clippy/tests/workspace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(lazy_cell)]

use std::path::PathBuf;
use std::process::Command;
use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE};
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-64453.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LL | static settings_dir: String = format!("");
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
= note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0507]: cannot move out of static item `settings_dir`
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/consts/issue-16538.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
= note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`

error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:11:22
Expand Down
Loading

0 comments on commit f3b13b3

Please sign in to comment.