summaryrefslogtreecommitdiffstats
path: root/vendor/once_cell/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/once_cell/src')
-rw-r--r--vendor/once_cell/src/imp_cs.rs2
-rw-r--r--vendor/once_cell/src/imp_pl.rs4
-rw-r--r--vendor/once_cell/src/imp_std.rs20
-rw-r--r--vendor/once_cell/src/lib.rs163
-rw-r--r--vendor/once_cell/src/race.rs2
5 files changed, 104 insertions, 87 deletions
diff --git a/vendor/once_cell/src/imp_cs.rs b/vendor/once_cell/src/imp_cs.rs
index 668f18ec6..04018f119 100644
--- a/vendor/once_cell/src/imp_cs.rs
+++ b/vendor/once_cell/src/imp_cs.rs
@@ -63,7 +63,7 @@ impl<T> OnceCell<T> {
pub(crate) unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
// SAFETY: The caller ensures that the value is initialized and access synchronized.
- crate::unwrap_unchecked(self.value.borrow(CriticalSection::new()).get())
+ self.value.borrow(CriticalSection::new()).get().unwrap_unchecked()
}
#[inline]
diff --git a/vendor/once_cell/src/imp_pl.rs b/vendor/once_cell/src/imp_pl.rs
index 84d859386..37a85547d 100644
--- a/vendor/once_cell/src/imp_pl.rs
+++ b/vendor/once_cell/src/imp_pl.rs
@@ -58,7 +58,7 @@ impl<T> OnceCell<T> {
// but that is more complicated
// - finally, if it returns Ok, we store the value and store the flag with
// `Release`, which synchronizes with `Acquire`s.
- let f = unsafe { crate::unwrap_unchecked(f.take()) };
+ let f = unsafe { f.take().unwrap_unchecked() };
match f() {
Ok(value) => unsafe {
// Safe b/c we have a unique access and no panic may happen
@@ -101,7 +101,7 @@ impl<T> OnceCell<T> {
pub(crate) unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
let slot = &*self.value.get();
- crate::unwrap_unchecked(slot.as_ref())
+ slot.as_ref().unwrap_unchecked()
}
/// Gets the mutable reference to the underlying value.
diff --git a/vendor/once_cell/src/imp_std.rs b/vendor/once_cell/src/imp_std.rs
index 5761f0184..3b9e6d205 100644
--- a/vendor/once_cell/src/imp_std.rs
+++ b/vendor/once_cell/src/imp_std.rs
@@ -5,7 +5,6 @@
use std::{
cell::{Cell, UnsafeCell},
- marker::PhantomData,
panic::{RefUnwindSafe, UnwindSafe},
sync::atomic::{AtomicBool, AtomicPtr, Ordering},
thread::{self, Thread},
@@ -22,7 +21,6 @@ pub(crate) struct OnceCell<T> {
// State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states
// allow waiters.
queue: AtomicPtr<Waiter>,
- _marker: PhantomData<*mut Waiter>,
value: UnsafeCell<Option<T>>,
}
@@ -39,19 +37,11 @@ impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
impl<T> OnceCell<T> {
pub(crate) const fn new() -> OnceCell<T> {
- OnceCell {
- queue: AtomicPtr::new(INCOMPLETE_PTR),
- _marker: PhantomData,
- value: UnsafeCell::new(None),
- }
+ OnceCell { queue: AtomicPtr::new(INCOMPLETE_PTR), value: UnsafeCell::new(None) }
}
pub(crate) const fn with_value(value: T) -> OnceCell<T> {
- OnceCell {
- queue: AtomicPtr::new(COMPLETE_PTR),
- _marker: PhantomData,
- value: UnsafeCell::new(Some(value)),
- }
+ OnceCell { queue: AtomicPtr::new(COMPLETE_PTR), value: UnsafeCell::new(Some(value)) }
}
/// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
@@ -78,7 +68,7 @@ impl<T> OnceCell<T> {
initialize_or_wait(
&self.queue,
Some(&mut || {
- let f = unsafe { crate::unwrap_unchecked(f.take()) };
+ let f = unsafe { f.take().unwrap_unchecked() };
match f() {
Ok(value) => {
unsafe { *slot = Some(value) };
@@ -109,7 +99,7 @@ impl<T> OnceCell<T> {
pub(crate) unsafe fn get_unchecked(&self) -> &T {
debug_assert!(self.is_initialized());
let slot = &*self.value.get();
- crate::unwrap_unchecked(slot.as_ref())
+ slot.as_ref().unwrap_unchecked()
}
/// Gets the mutable reference to the underlying value.
@@ -209,7 +199,7 @@ fn initialize_or_wait(queue: &AtomicPtr<Waiter>, mut init: Option<&mut dyn FnMut
return;
}
(INCOMPLETE, None) | (RUNNING, _) => {
- wait(&queue, curr_queue);
+ wait(queue, curr_queue);
curr_queue = queue.load(Ordering::Acquire);
}
_ => debug_assert!(false),
diff --git a/vendor/once_cell/src/lib.rs b/vendor/once_cell/src/lib.rs
index c2061f89f..db7e19a8a 100644
--- a/vendor/once_cell/src/lib.rs
+++ b/vendor/once_cell/src/lib.rs
@@ -1,8 +1,10 @@
//! # Overview
//!
-//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and [`sync::OnceCell`]. A `OnceCell`
-//! might store arbitrary non-`Copy` types, can be assigned to at most once and provides direct access
-//! to the stored contents. The core API looks *roughly* like this (and there's much more inside, read on!):
+//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and
+//! [`sync::OnceCell`]. A `OnceCell` might store arbitrary non-`Copy` types, can
+//! be assigned to at most once and provides direct access to the stored
+//! contents. The core API looks *roughly* like this (and there's much more
+//! inside, read on!):
//!
//! ```rust,ignore
//! impl<T> OnceCell<T> {
@@ -12,11 +14,12 @@
//! }
//! ```
//!
-//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires only a shared reference.
-//! Because of the single assignment restriction `get` can return a `&T` instead of `Ref<T>`
-//! or `MutexGuard<T>`.
+//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires
+//! only a shared reference. Because of the single assignment restriction `get`
+//! can return a `&T` instead of `Ref<T>` or `MutexGuard<T>`.
//!
-//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait), while the `unsync` one is not.
+//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait),
+//! while the `unsync` one is not.
//!
//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html
//! [`sync::OnceCell`]: sync/struct.OnceCell.html
@@ -79,7 +82,8 @@
//! }
//! ```
//!
-//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to streamline this pattern:
+//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to
+//! streamline this pattern:
//!
//! ```rust
//! use std::{sync::Mutex, collections::HashMap};
@@ -120,7 +124,8 @@
//! ```
//!
//! If you need a lazy field in a struct, you probably should use `OnceCell`
-//! directly, because that will allow you to access `self` during initialization.
+//! directly, because that will allow you to access `self` during
+//! initialization.
//!
//! ```rust
//! use std::{fs, path::PathBuf};
@@ -156,7 +161,8 @@
//! }
//! ```
//!
-//! This macro can be useful to avoid the "compile regex on every loop iteration" problem.
+//! This macro can be useful to avoid the "compile regex on every loop
+//! iteration" problem.
//!
//! ## Runtime `include_bytes!`
//!
@@ -243,7 +249,7 @@
//! let b = B::default();
//! a.b.init(&b);
//! b.a.init(&a);
-//!
+//!
//! let _a = &a.b.a.b.a;
//! }
//! ```
@@ -262,23 +268,28 @@
//! |`Mutex<T>` | `MutexGuard<T>` | may deadlock at runtime, may block the thread |
//! |`sync::OnceCell<T>` | `&T` | assignable only once, may block the thread |
//!
-//! Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
-//! itself. However, because the assignment can happen only once, such cases should be more rare than
-//! equivalents with `RefCell` and `Mutex`.
+//! Technically, calling `get_or_init` will also cause a panic or a deadlock if
+//! it recursively calls itself. However, because the assignment can happen only
+//! once, such cases should be more rare than equivalents with `RefCell` and
+//! `Mutex`.
//!
//! # Minimum Supported `rustc` Version
//!
//! This crate's minimum supported `rustc` version is `1.56.0`.
//!
-//! If only the `std` feature is enabled, MSRV will be updated conservatively, supporting at least latest 8 versions of the compiler.
-//! When using other features, like `parking_lot`, MSRV might be updated more frequently, up to the latest stable.
-//! In both cases, increasing MSRV is *not* considered a semver-breaking change.
+//! If only the `std` feature is enabled, MSRV will be updated conservatively,
+//! supporting at least latest 8 versions of the compiler. When using other
+//! features, like `parking_lot`, MSRV might be updated more frequently, up to
+//! the latest stable. In both cases, increasing MSRV is *not* considered a
+//! semver-breaking change.
//!
//! # Implementation details
//!
-//! The implementation is based on the [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/)
-//! and [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and [`std::sync::Once`]. In some sense,
-//! `once_cell` just streamlines and unifies those APIs.
+//! The implementation is based on the
+//! [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/) and
+//! [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and
+//! [`std::sync::Once`]. In some sense, `once_cell` just streamlines and unifies
+//! those APIs.
//!
//! To implement a sync flavor of `OnceCell`, this crates uses either a custom
//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is
@@ -292,46 +303,66 @@
//!
//! # F.A.Q.
//!
-//! **Should I use lazy_static or once_cell?**
+//! **Should I use the sync or unsync flavor?**
//!
-//! To the first approximation, `once_cell` is both more flexible and more convenient than `lazy_static`
-//! and should be preferred.
+//! Because Rust compiler checks thread safety for you, it's impossible to
+//! accidentally use `unsync` where `sync` is required. So, use `unsync` in
+//! single-threaded code and `sync` in multi-threaded. It's easy to switch
+//! between the two if code becomes multi-threaded later.
//!
-//! Unlike `once_cell`, `lazy_static` supports spinlock-based implementation of blocking which works with
-//! `#![no_std]`.
+//! At the moment, `unsync` has an additional benefit that reentrant
+//! initialization causes a panic, which might be easier to debug than a
+//! deadlock.
//!
-//! `lazy_static` has received significantly more real world testing, but `once_cell` is also a widely
-//! used crate.
+//! **Does this crate support async?**
//!
-//! **Should I use the sync or unsync flavor?**
+//! No, but you can use
+//! [`async_once_cell`](https://crates.io/crates/async_once_cell) instead.
//!
-//! Because Rust compiler checks thread safety for you, it's impossible to accidentally use `unsync` where
-//! `sync` is required. So, use `unsync` in single-threaded code and `sync` in multi-threaded. It's easy
-//! to switch between the two if code becomes multi-threaded later.
+//! **Does this crate support `no_std`?**
//!
-//! At the moment, `unsync` has an additional benefit that reentrant initialization causes a panic, which
-//! might be easier to debug than a deadlock.
+//! Yes, but with caveats. `OnceCell` is a synchronization primitive which
+//! _semantically_ relies on blocking. `OnceCell` guarantees that at most one
+//! `f` will be called to compute the value. If two threads of execution call
+//! `get_or_init` concurrently, one of them has to wait.
//!
-//! **Does this crate support async?**
+//! Waiting fundamentally requires OS support. Execution environment needs to
+//! understand who waits on whom to prevent deadlocks due to priority inversion.
+//! You _could_ make code to compile by blindly using pure spinlocks, but the
+//! runtime behavior would be subtly wrong.
+//!
+//! Given these constraints, `once_cell` provides the following options:
//!
-//! No, but you can use [`async_once_cell`](https://crates.io/crates/async_once_cell) instead.
+//! - The `race` module provides similar, but distinct synchronization primitive
+//! which is compatible with `no_std`. With `race`, the `f` function can be
+//! called multiple times by different threads, but only one thread will win
+//! to install the value.
+//! - `critical-section` feature (with a `-`, not `_`) uses `critical_section`
+//! to implement blocking.
//!
//! **Can I bring my own mutex?**
//!
-//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to allow just that.
+//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to
+//! allow just that.
+//!
+//! **Should I use `std::cell::OnceCell`, `once_cell`, or `lazy_static`?**
+//!
+//! If you can use `std` version (your MSRV is at least 1.70, and you don't need
+//! extra features `once_cell` provides), use `std`. Otherwise, use `once_cell`.
+//! Don't use `lazy_static`.
//!
//! # Related crates
//!
+//! * Most of this crate's functionality is available in `std` starting with
+//! Rust 1.70. See `std::cell::OnceCell` and `std::sync::OnceLock`.
//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell)
//! * [lazy-init](https://crates.io/crates/lazy-init)
//! * [lazycell](https://crates.io/crates/lazycell)
//! * [mitochondria](https://crates.io/crates/mitochondria)
//! * [lazy_static](https://crates.io/crates/lazy_static)
//! * [async_once_cell](https://crates.io/crates/async_once_cell)
-//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring your own mutex)
-//!
-//! Most of this crate's functionality is available in `std` in nightly Rust.
-//! See the [tracking issue](https://github.com/rust-lang/rust/issues/74465).
+//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring
+//! your own mutex)
#![cfg_attr(not(feature = "std"), no_std)]
@@ -359,8 +390,6 @@ pub mod unsync {
panic::{RefUnwindSafe, UnwindSafe},
};
- use super::unwrap_unchecked;
-
/// A cell which can be written to only once. It is not thread safe.
///
/// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
@@ -532,7 +561,7 @@ pub mod unsync {
// checked that slot is currently `None`, so this write
// maintains the `inner`'s invariant.
*slot = Some(value);
- Ok(unsafe { unwrap_unchecked(slot.as_ref()) })
+ Ok(unsafe { slot.as_ref().unwrap_unchecked() })
}
/// Gets the contents of the cell, initializing it with `f`
@@ -605,7 +634,7 @@ pub mod unsync {
// `assert`, while keeping `set/get` would be sound, but it seems
// better to panic, rather than to silently use an old value.
assert!(self.set(val).is_ok(), "reentrant init");
- Ok(unsafe { unwrap_unchecked(self.get()) })
+ Ok(unsafe { self.get().unwrap_unchecked() })
}
/// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
@@ -638,7 +667,7 @@ pub mod unsync {
/// cell = OnceCell::new();
/// ```
pub fn take(&mut self) -> Option<T> {
- mem::replace(self, Self::default()).into_inner()
+ mem::take(self).into_inner()
}
/// Consumes the `OnceCell`, returning the wrapped value.
@@ -765,8 +794,14 @@ pub mod unsync {
/// assert_eq!(*lazy, 92);
/// ```
pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
- Self::force(this);
- Self::get_mut(this).unwrap_or_else(|| unreachable!())
+ if this.cell.get_mut().is_none() {
+ let value = match this.init.get_mut().take() {
+ Some(f) => f(),
+ None => panic!("Lazy instance has previously been poisoned"),
+ };
+ this.cell = OnceCell::with_value(value);
+ }
+ this.cell.get_mut().unwrap_or_else(|| unreachable!())
}
/// Gets the reference to the result of this lazy value if
@@ -813,8 +848,7 @@ pub mod unsync {
impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
fn deref_mut(&mut self) -> &mut T {
- Lazy::force(self);
- self.cell.get_mut().unwrap_or_else(|| unreachable!())
+ Lazy::force_mut(self)
}
}
@@ -836,7 +870,7 @@ pub mod sync {
panic::RefUnwindSafe,
};
- use super::{imp::OnceCell as Imp, unwrap_unchecked};
+ use super::imp::OnceCell as Imp;
/// A thread-safe cell which can be written to only once.
///
@@ -1047,7 +1081,7 @@ pub mod sync {
/// ```
pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
let mut value = Some(value);
- let res = self.get_or_init(|| unsafe { unwrap_unchecked(value.take()) });
+ let res = self.get_or_init(|| unsafe { value.take().unwrap_unchecked() });
match value {
None => Ok(res),
Some(value) => Err((res, value)),
@@ -1163,7 +1197,7 @@ pub mod sync {
/// cell = OnceCell::new();
/// ```
pub fn take(&mut self) -> Option<T> {
- mem::replace(self, Self::default()).into_inner()
+ mem::take(self).into_inner()
}
/// Consumes the `OnceCell`, returning the wrapped value. Returns
@@ -1293,8 +1327,14 @@ pub mod sync {
/// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92);
/// ```
pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
- Self::force(this);
- Self::get_mut(this).unwrap_or_else(|| unreachable!())
+ if this.cell.get_mut().is_none() {
+ let value = match this.init.get_mut().take() {
+ Some(f) => f(),
+ None => panic!("Lazy instance has previously been poisoned"),
+ };
+ this.cell = OnceCell::with_value(value);
+ }
+ this.cell.get_mut().unwrap_or_else(|| unreachable!())
}
/// Gets the reference to the result of this lazy value if
@@ -1341,8 +1381,7 @@ pub mod sync {
impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
fn deref_mut(&mut self) -> &mut T {
- Lazy::force(self);
- self.cell.get_mut().unwrap_or_else(|| unreachable!())
+ Lazy::force_mut(self)
}
}
@@ -1373,15 +1412,3 @@ pub mod sync {
#[cfg(feature = "race")]
pub mod race;
-
-// Remove once MSRV is at least 1.58.
-#[inline]
-unsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
- match val {
- Some(value) => value,
- None => {
- debug_assert!(false);
- core::hint::unreachable_unchecked()
- }
- }
-}
diff --git a/vendor/once_cell/src/race.rs b/vendor/once_cell/src/race.rs
index ee3d51a58..fe36fa174 100644
--- a/vendor/once_cell/src/race.rs
+++ b/vendor/once_cell/src/race.rs
@@ -351,7 +351,7 @@ mod once_box {
Ordering::AcqRel,
Ordering::Acquire,
);
- if let Err(_) = exchange {
+ if exchange.is_err() {
let value = unsafe { Box::from_raw(ptr) };
return Err(value);
}