diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/once_cell | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/once_cell')
-rw-r--r-- | vendor/once_cell/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/once_cell/CHANGELOG.md | 11 | ||||
-rw-r--r-- | vendor/once_cell/Cargo.lock | 101 | ||||
-rw-r--r-- | vendor/once_cell/Cargo.toml | 29 | ||||
-rw-r--r-- | vendor/once_cell/examples/bench_vs_lazy_static.rs | 51 | ||||
-rw-r--r-- | vendor/once_cell/src/imp_cs.rs | 2 | ||||
-rw-r--r-- | vendor/once_cell/src/imp_pl.rs | 4 | ||||
-rw-r--r-- | vendor/once_cell/src/imp_std.rs | 20 | ||||
-rw-r--r-- | vendor/once_cell/src/lib.rs | 163 | ||||
-rw-r--r-- | vendor/once_cell/src/race.rs | 2 | ||||
-rw-r--r-- | vendor/once_cell/tests/it.rs | 977 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/main.rs | 12 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/race.rs | 128 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/race_once_box.rs | 145 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/sync_lazy.rs | 176 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/sync_once_cell.rs | 309 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/unsync_lazy.rs | 134 | ||||
-rw-r--r-- | vendor/once_cell/tests/it/unsync_once_cell.rs | 154 |
18 files changed, 1231 insertions, 1189 deletions
diff --git a/vendor/once_cell/.cargo-checksum.json b/vendor/once_cell/.cargo-checksum.json index 5f6558293..4cb726782 100644 --- a/vendor/once_cell/.cargo-checksum.json +++ b/vendor/once_cell/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"0cc0b7a536c63969dfe9a3482ad35be72368ae10bcb38522375ab1956f1d34d8","Cargo.lock":"8a37d0df9b1582a7f19959e9c7076de4e94bbf14d4a8cc993482cac1817ccd11","Cargo.toml":"0c350a2582981f0096c51368eba98e2ae554c523542322d06d58943d1883c346","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"e883909b29dc4d1c44270136fe2cfe7b2df6b416226b13928fdf9f1e15130be7","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/bench_vs_lazy_static.rs":"d527294a2e73b53ac5faed8b316dfd1ae2a06adb31384134af21f10ce76333a5","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_cs.rs":"888fc76a1f4e55b1ece3ef748b0aa6a47be2d8d928c10f89ae6b4f12330c0e55","src/imp_pl.rs":"cd69042890c25fd3db97a4762abea4b814c961eadaf5d6ed7c7db17a6abd4c5b","src/imp_std.rs":"f13a5bfe08ac02eb0d5a0271cb5be9e8c534a81cddc3253aaca28b69bded8e65","src/lib.rs":"1458bb31d52c5c79d61077c8adb042afedab295a1744def7aa591bbbf005d1ba","src/race.rs":"eb977c7caed88774699fea6ac25afdfde0bad211c7a20c64a06dabcdc38e8a29","tests/it.rs":"41f50496463a0036c45ed138f158d221d379e50a91ca452ba8ffe8caa7a59e3a"},"package":"b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"}
\ No newline at end of file +{"files":{"CHANGELOG.md":"24f417c25ccab9a49ff4b3b16b0da609517fd81b443df8e1b5f96322f997fb0b","Cargo.lock":"07dcbd89a8fb48503b73e50f44aa46cbb5ada9b2d9593cdb879226feaecc541f","Cargo.toml":"0682d1bd57d5d43262af293a755d29df111a515f00a60d70246947a37f8e7be3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"e883909b29dc4d1c44270136fe2cfe7b2df6b416226b13928fdf9f1e15130be7","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_cs.rs":"2f99fd6f993393bc98fd7b52203b1f210262cc834fb30661e0e7f66bc487d357","src/imp_pl.rs":"6a97f60a91ab44192dcaf028e987f6be0328b5d4d69216dcdaec93bc39401f68","src/imp_std.rs":"1c130f83be5c1360dfd379911f97797c1e4c730b845f465c8c2630467ca317d2","src/lib.rs":"cdb40128852d5624120aa49fa82ca573800d955f9c35144878604307c487bdce","src/race.rs":"917f1bc0ba2887644da447a6e9e38990c9a12e3c41c980be37ee916bf79d7677","tests/it/main.rs":"e6e9987e053af84b9d76052602995b1e777efb5bc06cd5f49009e6f03b18626c","tests/it/race.rs":"8dfe38563b6d0be890ab076be1fc1122d41a7c7792354cd7f60bc4454666b968","tests/it/race_once_box.rs":"1c2fe9e2988ec38d60c93c797fceb4c7a65d1b2e48a6a1e78db78ab91388e844","tests/it/sync_lazy.rs":"a36c5d66340b3d6d20aad331a499858a2125dfdfd624c5bf3b4b06a0b157c75c","tests/it/sync_once_cell.rs":"0d04beeb394eb53dd3fc0309fcfc382d56350e72b89d22356e0047d6c7bfef58","tests/it/unsync_lazy.rs":"51a1ffd411770d1e32399ec23feb5f61be362bbed34e100eb7509f8496224e1a","tests/it/unsync_once_cell.rs":"82b72936d7bd4090db25cfc543c01ef3206d6917ac56f09d17d4110a65deb30a"},"package":"dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"}
\ No newline at end of file diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md index bf489b25b..0cb846a4f 100644 --- a/vendor/once_cell/CHANGELOG.md +++ b/vendor/once_cell/CHANGELOG.md @@ -2,7 +2,16 @@ ## Unreleased -- +- + +## 1.18.0 + +- `MSRV` is updated to 1.60.0 to take advantage of `dep:` syntax for cargo features, + removing "implementation details" from publicly visible surface. + +## 1.17.2 + +- Avoid unnecessary synchronization in `Lazy::{force,deref}_mut()`, [#231](https://github.com/matklad/once_cell/pull/231). ## 1.17.1 diff --git a/vendor/once_cell/Cargo.lock b/vendor/once_cell/Cargo.lock index 0ece6bb92..c545648c6 100644 --- a/vendor/once_cell/Cargo.lock +++ b/vendor/once_cell/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] [[package]] name = "atomic-polyfill" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d299f547288d6db8d5c3a2916f7b2f66134b15b8c1ac1c4357dd3b8752af7bb2" +checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" dependencies = [ "critical-section", ] @@ -39,26 +39,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] -name = "crossbeam-utils" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" -dependencies = [ - "cfg-if", - "once_cell 1.14.0", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] name = "libc" -version = "0.2.132" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "memchr" @@ -68,27 +52,19 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "once_cell" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" - -[[package]] -name = "once_cell" -version = "1.17.1" +version = "1.18.0" dependencies = [ "atomic-polyfill", "critical-section", - "crossbeam-utils", - "lazy_static", "parking_lot_core", "regex", ] [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", @@ -108,9 +84,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick", "memchr", @@ -119,55 +95,78 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ + "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", + "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml index 76a629114..b3a6ba60b 100644 --- a/vendor/once_cell/Cargo.toml +++ b/vendor/once_cell/Cargo.toml @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.56" +rust-version = "1.60" name = "once_cell" -version = "1.17.1" +version = "1.18.0" authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"] exclude = [ "*.png", @@ -47,10 +47,6 @@ name = "bench_acquire" required-features = ["std"] [[example]] -name = "bench_vs_lazy_static" -required-features = ["std"] - -[[example]] name = "lazy_static" required-features = ["std"] @@ -66,31 +62,22 @@ required-features = ["std"] name = "test_synchronization" required-features = ["std"] -[dependencies.atomic_polyfill] +[dependencies.atomic-polyfill] version = "1" optional = true -package = "atomic-polyfill" -[dependencies.critical_section] +[dependencies.critical-section] version = "1" optional = true -package = "critical-section" [dependencies.parking_lot_core] version = "0.9.3" optional = true default_features = false -[dev-dependencies.critical_section] +[dev-dependencies.critical-section] version = "1.1.1" features = ["std"] -package = "critical-section" - -[dev-dependencies.crossbeam-utils] -version = "0.8.7" - -[dev-dependencies.lazy_static] -version = "1.0.0" [dev-dependencies.regex] version = "1.2.0" @@ -99,11 +86,11 @@ version = "1.2.0" alloc = ["race"] atomic-polyfill = ["critical-section"] critical-section = [ - "critical_section", - "atomic_polyfill", + "dep:critical-section", + "dep:atomic-polyfill", ] default = ["std"] -parking_lot = ["parking_lot_core"] +parking_lot = ["dep:parking_lot_core"] race = [] std = ["alloc"] unstable = [] diff --git a/vendor/once_cell/examples/bench_vs_lazy_static.rs b/vendor/once_cell/examples/bench_vs_lazy_static.rs deleted file mode 100644 index c23b0124e..000000000 --- a/vendor/once_cell/examples/bench_vs_lazy_static.rs +++ /dev/null @@ -1,51 +0,0 @@ -use lazy_static::lazy_static; -use once_cell::sync::Lazy; - -const N_THREADS: usize = 32; -const N_ROUNDS: usize = 100_000_000; - -static ONCE_CELL: Lazy<Vec<String>> = Lazy::new(|| vec!["Spica".to_string(), "Hoyten".to_string()]); - -lazy_static! { - static ref LAZY_STATIC: Vec<String> = vec!["Spica".to_string(), "Hoyten".to_string()]; -} - -fn main() { - let once_cell = { - let start = std::time::Instant::now(); - let threads = (0..N_THREADS) - .map(|_| std::thread::spawn(move || thread_once_cell())) - .collect::<Vec<_>>(); - for thread in threads { - thread.join().unwrap(); - } - start.elapsed() - }; - let lazy_static = { - let start = std::time::Instant::now(); - let threads = (0..N_THREADS) - .map(|_| std::thread::spawn(move || thread_lazy_static())) - .collect::<Vec<_>>(); - for thread in threads { - thread.join().unwrap(); - } - start.elapsed() - }; - - println!("once_cell: {:?}", once_cell); - println!("lazy_static: {:?}", lazy_static); -} - -fn thread_once_cell() { - for _ in 0..N_ROUNDS { - let len = ONCE_CELL.len(); - assert_eq!(len, 2) - } -} - -fn thread_lazy_static() { - for _ in 0..N_ROUNDS { - let len = LAZY_STATIC.len(); - assert_eq!(len, 2) - } -} 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); } diff --git a/vendor/once_cell/tests/it.rs b/vendor/once_cell/tests/it.rs deleted file mode 100644 index d18f0a165..000000000 --- a/vendor/once_cell/tests/it.rs +++ /dev/null @@ -1,977 +0,0 @@ -mod unsync { - use core::{ - cell::Cell, - sync::atomic::{AtomicUsize, Ordering::SeqCst}, - }; - - use once_cell::unsync::{Lazy, OnceCell}; - - #[test] - fn once_cell() { - let c = OnceCell::new(); - assert!(c.get().is_none()); - c.get_or_init(|| 92); - assert_eq!(c.get(), Some(&92)); - - c.get_or_init(|| panic!("Kabom!")); - assert_eq!(c.get(), Some(&92)); - } - - #[test] - fn once_cell_with_value() { - const CELL: OnceCell<i32> = OnceCell::with_value(12); - let cell = CELL; - assert_eq!(cell.get(), Some(&12)); - } - - #[test] - fn once_cell_get_mut() { - let mut c = OnceCell::new(); - assert!(c.get_mut().is_none()); - c.set(90).unwrap(); - *c.get_mut().unwrap() += 2; - assert_eq!(c.get_mut(), Some(&mut 92)); - } - - #[test] - fn once_cell_drop() { - static DROP_CNT: AtomicUsize = AtomicUsize::new(0); - struct Dropper; - impl Drop for Dropper { - fn drop(&mut self) { - DROP_CNT.fetch_add(1, SeqCst); - } - } - - let x = OnceCell::new(); - x.get_or_init(|| Dropper); - assert_eq!(DROP_CNT.load(SeqCst), 0); - drop(x); - assert_eq!(DROP_CNT.load(SeqCst), 1); - } - - #[test] - fn unsync_once_cell_drop_empty() { - let x = OnceCell::<String>::new(); - drop(x); - } - - #[test] - fn clone() { - let s = OnceCell::new(); - let c = s.clone(); - assert!(c.get().is_none()); - - s.set("hello".to_string()).unwrap(); - let c = s.clone(); - assert_eq!(c.get().map(String::as_str), Some("hello")); - } - - #[test] - fn from_impl() { - assert_eq!(OnceCell::from("value").get(), Some(&"value")); - assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); - } - - #[test] - fn partialeq_impl() { - assert!(OnceCell::from("value") == OnceCell::from("value")); - assert!(OnceCell::from("foo") != OnceCell::from("bar")); - - assert!(OnceCell::<String>::new() == OnceCell::new()); - assert!(OnceCell::<String>::new() != OnceCell::from("value".to_owned())); - } - - #[test] - fn into_inner() { - let cell: OnceCell<String> = OnceCell::new(); - assert_eq!(cell.into_inner(), None); - let cell = OnceCell::new(); - cell.set("hello".to_string()).unwrap(); - assert_eq!(cell.into_inner(), Some("hello".to_string())); - } - - #[test] - fn debug_impl() { - let cell = OnceCell::new(); - assert_eq!(format!("{:?}", cell), "OnceCell(Uninit)"); - cell.set("hello".to_string()).unwrap(); - assert_eq!(format!("{:?}", cell), "OnceCell(\"hello\")"); - } - - #[test] - fn lazy_new() { - let called = Cell::new(0); - let x = Lazy::new(|| { - called.set(called.get() + 1); - 92 - }); - - assert_eq!(called.get(), 0); - - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.get(), 1); - - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.get(), 1); - } - - #[test] - fn lazy_deref_mut() { - let called = Cell::new(0); - let mut x = Lazy::new(|| { - called.set(called.get() + 1); - 92 - }); - - assert_eq!(called.get(), 0); - - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.get(), 1); - - *x /= 2; - assert_eq!(*x, 46); - assert_eq!(called.get(), 1); - } - - #[test] - fn lazy_force_mut() { - let called = Cell::new(0); - let mut x = Lazy::new(|| { - called.set(called.get() + 1); - 92 - }); - assert_eq!(called.get(), 0); - let v = Lazy::force_mut(&mut x); - assert_eq!(called.get(), 1); - - *v /= 2; - assert_eq!(*x, 46); - assert_eq!(called.get(), 1); - } - - #[test] - fn lazy_get_mut() { - let called = Cell::new(0); - let mut x: Lazy<u32, _> = Lazy::new(|| { - called.set(called.get() + 1); - 92 - }); - - assert_eq!(called.get(), 0); - assert_eq!(*x, 92); - - let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); - assert_eq!(called.get(), 1); - - *mut_ref /= 2; - assert_eq!(*x, 46); - assert_eq!(called.get(), 1); - } - - #[test] - fn lazy_default() { - static CALLED: AtomicUsize = AtomicUsize::new(0); - - struct Foo(u8); - impl Default for Foo { - fn default() -> Self { - CALLED.fetch_add(1, SeqCst); - Foo(42) - } - } - - let lazy: Lazy<std::sync::Mutex<Foo>> = <_>::default(); - - assert_eq!(CALLED.load(SeqCst), 0); - - assert_eq!(lazy.lock().unwrap().0, 42); - assert_eq!(CALLED.load(SeqCst), 1); - - lazy.lock().unwrap().0 = 21; - - assert_eq!(lazy.lock().unwrap().0, 21); - assert_eq!(CALLED.load(SeqCst), 1); - } - - #[test] - fn lazy_into_value() { - let l: Lazy<i32, _> = Lazy::new(|| panic!()); - assert!(matches!(Lazy::into_value(l), Err(_))); - let l = Lazy::new(|| -> i32 { 92 }); - Lazy::force(&l); - assert!(matches!(Lazy::into_value(l), Ok(92))); - } - - #[test] - #[cfg(feature = "std")] - fn lazy_poisoning() { - let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); - for _ in 0..2 { - let res = std::panic::catch_unwind(|| x.len()); - assert!(res.is_err()); - } - } - - #[test] - fn aliasing_in_get() { - let x = OnceCell::new(); - x.set(42).unwrap(); - let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option<T>` --+ - let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option<T>` | - println!("{}", at_x); // <------- up until here ---------------------------+ - } - - #[test] - #[should_panic(expected = "reentrant init")] - fn reentrant_init() { - let x: OnceCell<Box<i32>> = OnceCell::new(); - let dangling_ref: Cell<Option<&i32>> = Cell::new(None); - x.get_or_init(|| { - let r = x.get_or_init(|| Box::new(92)); - dangling_ref.set(Some(r)); - Box::new(62) - }); - eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); - } - - #[test] - // https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 - fn arrrrrrrrrrrrrrrrrrrrrr() { - let cell = OnceCell::new(); - { - let s = String::new(); - cell.set(&s).unwrap(); - } - } -} - -#[cfg(any(feature = "std", feature = "critical-section"))] -mod sync { - use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; - - #[cfg(feature = "std")] - use std::sync::Barrier; - - #[cfg(not(feature = "std"))] - use core::cell::Cell; - - use crossbeam_utils::thread::scope; - - use once_cell::sync::{Lazy, OnceCell}; - - #[test] - fn once_cell() { - let c = OnceCell::new(); - assert!(c.get().is_none()); - scope(|s| { - s.spawn(|_| { - c.get_or_init(|| 92); - assert_eq!(c.get(), Some(&92)); - }); - }) - .unwrap(); - c.get_or_init(|| panic!("Kabom!")); - assert_eq!(c.get(), Some(&92)); - } - - #[test] - fn once_cell_with_value() { - static CELL: OnceCell<i32> = OnceCell::with_value(12); - assert_eq!(CELL.get(), Some(&12)); - } - - #[test] - fn once_cell_get_mut() { - let mut c = OnceCell::new(); - assert!(c.get_mut().is_none()); - c.set(90).unwrap(); - *c.get_mut().unwrap() += 2; - assert_eq!(c.get_mut(), Some(&mut 92)); - } - - #[test] - fn once_cell_get_unchecked() { - let c = OnceCell::new(); - c.set(92).unwrap(); - unsafe { - assert_eq!(c.get_unchecked(), &92); - } - } - - #[test] - fn once_cell_drop() { - static DROP_CNT: AtomicUsize = AtomicUsize::new(0); - struct Dropper; - impl Drop for Dropper { - fn drop(&mut self) { - DROP_CNT.fetch_add(1, SeqCst); - } - } - - let x = OnceCell::new(); - scope(|s| { - s.spawn(|_| { - x.get_or_init(|| Dropper); - assert_eq!(DROP_CNT.load(SeqCst), 0); - drop(x); - }); - }) - .unwrap(); - assert_eq!(DROP_CNT.load(SeqCst), 1); - } - - #[test] - fn once_cell_drop_empty() { - let x = OnceCell::<String>::new(); - drop(x); - } - - #[test] - fn clone() { - let s = OnceCell::new(); - let c = s.clone(); - assert!(c.get().is_none()); - - s.set("hello".to_string()).unwrap(); - let c = s.clone(); - assert_eq!(c.get().map(String::as_str), Some("hello")); - } - - #[test] - fn get_or_try_init() { - let cell: OnceCell<String> = OnceCell::new(); - assert!(cell.get().is_none()); - - let res = - std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); - assert!(res.is_err()); - assert!(cell.get().is_none()); - - assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); - - assert_eq!( - cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), - Ok(&"hello".to_string()) - ); - assert_eq!(cell.get(), Some(&"hello".to_string())); - } - - #[cfg(feature = "std")] - #[test] - fn wait() { - let cell: OnceCell<String> = OnceCell::new(); - scope(|s| { - s.spawn(|_| cell.set("hello".to_string())); - let greeting = cell.wait(); - assert_eq!(greeting, "hello") - }) - .unwrap(); - } - - #[cfg(feature = "std")] - #[test] - fn get_or_init_stress() { - let n_threads = if cfg!(miri) { 30 } else { 1_000 }; - let n_cells = if cfg!(miri) { 30 } else { 1_000 }; - let cells: Vec<_> = std::iter::repeat_with(|| (Barrier::new(n_threads), OnceCell::new())) - .take(n_cells) - .collect(); - scope(|s| { - for t in 0..n_threads { - let cells = &cells; - s.spawn(move |_| { - for (i, (b, s)) in cells.iter().enumerate() { - b.wait(); - let j = if t % 2 == 0 { s.wait() } else { s.get_or_init(|| i) }; - assert_eq!(*j, i); - } - }); - } - }) - .unwrap(); - } - - #[test] - fn from_impl() { - assert_eq!(OnceCell::from("value").get(), Some(&"value")); - assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); - } - - #[test] - fn partialeq_impl() { - assert!(OnceCell::from("value") == OnceCell::from("value")); - assert!(OnceCell::from("foo") != OnceCell::from("bar")); - - assert!(OnceCell::<String>::new() == OnceCell::new()); - assert!(OnceCell::<String>::new() != OnceCell::from("value".to_owned())); - } - - #[test] - fn into_inner() { - let cell: OnceCell<String> = OnceCell::new(); - assert_eq!(cell.into_inner(), None); - let cell = OnceCell::new(); - cell.set("hello".to_string()).unwrap(); - assert_eq!(cell.into_inner(), Some("hello".to_string())); - } - - #[test] - fn debug_impl() { - let cell = OnceCell::new(); - assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); - cell.set(vec!["hello", "world"]).unwrap(); - assert_eq!( - format!("{:#?}", cell), - r#"OnceCell( - [ - "hello", - "world", - ], -)"# - ); - } - - #[test] - #[cfg_attr(miri, ignore)] // miri doesn't support processes - #[cfg(feature = "std")] - fn reentrant_init() { - let examples_dir = { - let mut exe = std::env::current_exe().unwrap(); - exe.pop(); - exe.pop(); - exe.push("examples"); - exe - }; - let bin = examples_dir - .join("reentrant_init_deadlocks") - .with_extension(std::env::consts::EXE_EXTENSION); - let mut guard = Guard { child: std::process::Command::new(bin).spawn().unwrap() }; - std::thread::sleep(std::time::Duration::from_secs(2)); - let status = guard.child.try_wait().unwrap(); - assert!(status.is_none()); - - struct Guard { - child: std::process::Child, - } - - impl Drop for Guard { - fn drop(&mut self) { - let _ = self.child.kill(); - } - } - } - - #[cfg(not(feature = "std"))] - #[test] - #[should_panic(expected = "reentrant init")] - fn reentrant_init() { - let x: OnceCell<Box<i32>> = OnceCell::new(); - let dangling_ref: Cell<Option<&i32>> = Cell::new(None); - x.get_or_init(|| { - let r = x.get_or_init(|| Box::new(92)); - dangling_ref.set(Some(r)); - Box::new(62) - }); - eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); - } - - #[test] - fn lazy_new() { - let called = AtomicUsize::new(0); - let x = Lazy::new(|| { - called.fetch_add(1, SeqCst); - 92 - }); - - assert_eq!(called.load(SeqCst), 0); - - scope(|s| { - s.spawn(|_| { - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.load(SeqCst), 1); - }); - }) - .unwrap(); - - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.load(SeqCst), 1); - } - - #[test] - fn lazy_deref_mut() { - let called = AtomicUsize::new(0); - let mut x = Lazy::new(|| { - called.fetch_add(1, SeqCst); - 92 - }); - - assert_eq!(called.load(SeqCst), 0); - - let y = *x - 30; - assert_eq!(y, 62); - assert_eq!(called.load(SeqCst), 1); - - *x /= 2; - assert_eq!(*x, 46); - assert_eq!(called.load(SeqCst), 1); - } - - #[test] - fn lazy_default() { - static CALLED: AtomicUsize = AtomicUsize::new(0); - - struct Foo(u8); - impl Default for Foo { - fn default() -> Self { - CALLED.fetch_add(1, SeqCst); - Foo(42) - } - } - - let lazy: Lazy<std::sync::Mutex<Foo>> = <_>::default(); - - assert_eq!(CALLED.load(SeqCst), 0); - - assert_eq!(lazy.lock().unwrap().0, 42); - assert_eq!(CALLED.load(SeqCst), 1); - - lazy.lock().unwrap().0 = 21; - - assert_eq!(lazy.lock().unwrap().0, 21); - assert_eq!(CALLED.load(SeqCst), 1); - } - - #[test] - fn static_lazy() { - static XS: Lazy<Vec<i32>> = Lazy::new(|| { - let mut xs = Vec::new(); - xs.push(1); - xs.push(2); - xs.push(3); - xs - }); - scope(|s| { - s.spawn(|_| { - assert_eq!(&*XS, &vec![1, 2, 3]); - }); - }) - .unwrap(); - assert_eq!(&*XS, &vec![1, 2, 3]); - } - - #[test] - fn static_lazy_via_fn() { - fn xs() -> &'static Vec<i32> { - static XS: OnceCell<Vec<i32>> = OnceCell::new(); - XS.get_or_init(|| { - let mut xs = Vec::new(); - xs.push(1); - xs.push(2); - xs.push(3); - xs - }) - } - assert_eq!(xs(), &vec![1, 2, 3]); - } - - #[test] - fn lazy_into_value() { - let l: Lazy<i32, _> = Lazy::new(|| panic!()); - assert!(matches!(Lazy::into_value(l), Err(_))); - let l = Lazy::new(|| -> i32 { 92 }); - Lazy::force(&l); - assert!(matches!(Lazy::into_value(l), Ok(92))); - } - - #[test] - fn lazy_poisoning() { - let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); - for _ in 0..2 { - let res = std::panic::catch_unwind(|| x.len()); - assert!(res.is_err()); - } - } - - #[test] - fn once_cell_is_sync_send() { - fn assert_traits<T: Send + Sync>() {} - assert_traits::<OnceCell<String>>(); - assert_traits::<Lazy<String>>(); - } - - #[test] - fn eval_once_macro() { - macro_rules! eval_once { - (|| -> $ty:ty { - $($body:tt)* - }) => {{ - static ONCE_CELL: OnceCell<$ty> = OnceCell::new(); - fn init() -> $ty { - $($body)* - } - ONCE_CELL.get_or_init(init) - }}; - } - - let fib: &'static Vec<i32> = eval_once! { - || -> Vec<i32> { - let mut res = vec![1, 1]; - for i in 0..10 { - let next = res[i] + res[i + 1]; - res.push(next); - } - res - } - }; - assert_eq!(fib[5], 8) - } - - #[test] - fn once_cell_does_not_leak_partially_constructed_boxes() { - let n_tries = if cfg!(miri) { 10 } else { 100 }; - let n_readers = 10; - let n_writers = 3; - const MSG: &str = "Hello, World"; - - for _ in 0..n_tries { - let cell: OnceCell<String> = OnceCell::new(); - scope(|scope| { - for _ in 0..n_readers { - scope.spawn(|_| loop { - if let Some(msg) = cell.get() { - assert_eq!(msg, MSG); - break; - } - }); - } - for _ in 0..n_writers { - let _ = scope.spawn(|_| cell.set(MSG.to_owned())); - } - }) - .unwrap() - } - } - - #[cfg(feature = "std")] - #[test] - fn get_does_not_block() { - let cell = OnceCell::new(); - let barrier = Barrier::new(2); - scope(|scope| { - scope.spawn(|_| { - cell.get_or_init(|| { - barrier.wait(); - barrier.wait(); - "hello".to_string() - }); - }); - barrier.wait(); - assert_eq!(cell.get(), None); - barrier.wait(); - }) - .unwrap(); - assert_eq!(cell.get(), Some(&"hello".to_string())); - } - - #[test] - // https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 - fn arrrrrrrrrrrrrrrrrrrrrr() { - let cell = OnceCell::new(); - { - let s = String::new(); - cell.set(&s).unwrap(); - } - } -} - -#[cfg(feature = "race")] -mod race { - #[cfg(feature = "std")] - use std::sync::Barrier; - use std::{ - num::NonZeroUsize, - sync::atomic::{AtomicUsize, Ordering::SeqCst}, - }; - - use crossbeam_utils::thread::scope; - - use once_cell::race::{OnceBool, OnceNonZeroUsize}; - - #[test] - fn once_non_zero_usize_smoke_test() { - let cnt = AtomicUsize::new(0); - let cell = OnceNonZeroUsize::new(); - let val = NonZeroUsize::new(92).unwrap(); - scope(|s| { - s.spawn(|_| { - assert_eq!( - cell.get_or_init(|| { - cnt.fetch_add(1, SeqCst); - val - }), - val - ); - assert_eq!(cnt.load(SeqCst), 1); - - assert_eq!( - cell.get_or_init(|| { - cnt.fetch_add(1, SeqCst); - val - }), - val - ); - assert_eq!(cnt.load(SeqCst), 1); - }); - }) - .unwrap(); - assert_eq!(cell.get(), Some(val)); - assert_eq!(cnt.load(SeqCst), 1); - } - - #[test] - fn once_non_zero_usize_set() { - let val1 = NonZeroUsize::new(92).unwrap(); - let val2 = NonZeroUsize::new(62).unwrap(); - - let cell = OnceNonZeroUsize::new(); - - assert!(cell.set(val1).is_ok()); - assert_eq!(cell.get(), Some(val1)); - - assert!(cell.set(val2).is_err()); - assert_eq!(cell.get(), Some(val1)); - } - - #[cfg(feature = "std")] - #[test] - fn once_non_zero_usize_first_wins() { - let val1 = NonZeroUsize::new(92).unwrap(); - let val2 = NonZeroUsize::new(62).unwrap(); - - let cell = OnceNonZeroUsize::new(); - - let b1 = Barrier::new(2); - let b2 = Barrier::new(2); - let b3 = Barrier::new(2); - scope(|s| { - s.spawn(|_| { - let r1 = cell.get_or_init(|| { - b1.wait(); - b2.wait(); - val1 - }); - assert_eq!(r1, val1); - b3.wait(); - }); - b1.wait(); - s.spawn(|_| { - let r2 = cell.get_or_init(|| { - b2.wait(); - b3.wait(); - val2 - }); - assert_eq!(r2, val1); - }); - }) - .unwrap(); - - assert_eq!(cell.get(), Some(val1)); - } - - #[test] - fn once_bool_smoke_test() { - let cnt = AtomicUsize::new(0); - let cell = OnceBool::new(); - scope(|s| { - s.spawn(|_| { - assert_eq!( - cell.get_or_init(|| { - cnt.fetch_add(1, SeqCst); - false - }), - false - ); - assert_eq!(cnt.load(SeqCst), 1); - - assert_eq!( - cell.get_or_init(|| { - cnt.fetch_add(1, SeqCst); - false - }), - false - ); - assert_eq!(cnt.load(SeqCst), 1); - }); - }) - .unwrap(); - assert_eq!(cell.get(), Some(false)); - assert_eq!(cnt.load(SeqCst), 1); - } - - #[test] - fn once_bool_set() { - let cell = OnceBool::new(); - - assert!(cell.set(false).is_ok()); - assert_eq!(cell.get(), Some(false)); - - assert!(cell.set(true).is_err()); - assert_eq!(cell.get(), Some(false)); - } -} - -#[cfg(all(feature = "race", feature = "alloc"))] -mod race_once_box { - #[cfg(feature = "std")] - use std::sync::Barrier; - use std::sync::{ - atomic::{AtomicUsize, Ordering::SeqCst}, - Arc, - }; - - #[cfg(feature = "std")] - use crossbeam_utils::thread::scope; - - use once_cell::race::OnceBox; - - #[derive(Default)] - struct Heap { - total: Arc<AtomicUsize>, - } - - #[derive(Debug)] - struct Pebble<T> { - val: T, - total: Arc<AtomicUsize>, - } - - impl<T> Drop for Pebble<T> { - fn drop(&mut self) { - self.total.fetch_sub(1, SeqCst); - } - } - - impl Heap { - fn total(&self) -> usize { - self.total.load(SeqCst) - } - fn new_pebble<T>(&self, val: T) -> Pebble<T> { - self.total.fetch_add(1, SeqCst); - Pebble { val, total: Arc::clone(&self.total) } - } - } - - #[cfg(feature = "std")] - #[test] - fn once_box_smoke_test() { - let heap = Heap::default(); - let global_cnt = AtomicUsize::new(0); - let cell = OnceBox::new(); - let b = Barrier::new(128); - scope(|s| { - for _ in 0..128 { - s.spawn(|_| { - let local_cnt = AtomicUsize::new(0); - cell.get_or_init(|| { - global_cnt.fetch_add(1, SeqCst); - local_cnt.fetch_add(1, SeqCst); - b.wait(); - Box::new(heap.new_pebble(())) - }); - assert_eq!(local_cnt.load(SeqCst), 1); - - cell.get_or_init(|| { - global_cnt.fetch_add(1, SeqCst); - local_cnt.fetch_add(1, SeqCst); - Box::new(heap.new_pebble(())) - }); - assert_eq!(local_cnt.load(SeqCst), 1); - }); - } - }) - .unwrap(); - assert!(cell.get().is_some()); - assert!(global_cnt.load(SeqCst) > 10); - - assert_eq!(heap.total(), 1); - drop(cell); - assert_eq!(heap.total(), 0); - } - - #[test] - fn once_box_set() { - let heap = Heap::default(); - let cell = OnceBox::new(); - assert!(cell.get().is_none()); - - assert!(cell.set(Box::new(heap.new_pebble("hello"))).is_ok()); - assert_eq!(cell.get().unwrap().val, "hello"); - assert_eq!(heap.total(), 1); - - assert!(cell.set(Box::new(heap.new_pebble("world"))).is_err()); - assert_eq!(cell.get().unwrap().val, "hello"); - assert_eq!(heap.total(), 1); - - drop(cell); - assert_eq!(heap.total(), 0); - } - - #[cfg(feature = "std")] - #[test] - fn once_box_first_wins() { - let cell = OnceBox::new(); - let val1 = 92; - let val2 = 62; - - let b1 = Barrier::new(2); - let b2 = Barrier::new(2); - let b3 = Barrier::new(2); - scope(|s| { - s.spawn(|_| { - let r1 = cell.get_or_init(|| { - b1.wait(); - b2.wait(); - Box::new(val1) - }); - assert_eq!(*r1, val1); - b3.wait(); - }); - b1.wait(); - s.spawn(|_| { - let r2 = cell.get_or_init(|| { - b2.wait(); - b3.wait(); - Box::new(val2) - }); - assert_eq!(*r2, val1); - }); - }) - .unwrap(); - - assert_eq!(cell.get(), Some(&val1)); - } - - #[test] - fn once_box_reentrant() { - let cell = OnceBox::new(); - let res = cell.get_or_init(|| { - cell.get_or_init(|| Box::new("hello".to_string())); - Box::new("world".to_string()) - }); - assert_eq!(res, "hello"); - } - - #[test] - fn once_box_default() { - struct Foo; - - let cell: OnceBox<Foo> = Default::default(); - assert!(cell.get().is_none()); - } -} diff --git a/vendor/once_cell/tests/it/main.rs b/vendor/once_cell/tests/it/main.rs new file mode 100644 index 000000000..b8e56ccc6 --- /dev/null +++ b/vendor/once_cell/tests/it/main.rs @@ -0,0 +1,12 @@ +mod unsync_once_cell; +#[cfg(any(feature = "std", feature = "critical-section"))] +mod sync_once_cell; + +mod unsync_lazy; +#[cfg(any(feature = "std", feature = "critical-section"))] +mod sync_lazy; + +#[cfg(feature = "race")] +mod race; +#[cfg(all(feature = "race", feature = "alloc"))] +mod race_once_box; diff --git a/vendor/once_cell/tests/it/race.rs b/vendor/once_cell/tests/it/race.rs new file mode 100644 index 000000000..24884dd82 --- /dev/null +++ b/vendor/once_cell/tests/it/race.rs @@ -0,0 +1,128 @@ +#[cfg(feature = "std")] +use std::sync::Barrier; +use std::{ + num::NonZeroUsize, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +use once_cell::race::{OnceBool, OnceNonZeroUsize}; + +#[test] +fn once_non_zero_usize_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceNonZeroUsize::new(); + let val = NonZeroUsize::new(92).unwrap(); + scope(|s| { + s.spawn(|| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }); + assert_eq!(cell.get(), Some(val)); + assert_eq!(cnt.load(SeqCst), 1); +} + +#[test] +fn once_non_zero_usize_set() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + assert!(cell.set(val1).is_ok()); + assert_eq!(cell.get(), Some(val1)); + + assert!(cell.set(val2).is_err()); + assert_eq!(cell.get(), Some(val1)); +} + +#[cfg(feature = "std")] +#[test] +fn once_non_zero_usize_first_wins() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + val1 + }); + assert_eq!(r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + val2 + }); + assert_eq!(r2, val1); + }); + }); + + assert_eq!(cell.get(), Some(val1)); +} + +#[test] +fn once_bool_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceBool::new(); + scope(|s| { + s.spawn(|| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }); + assert_eq!(cell.get(), Some(false)); + assert_eq!(cnt.load(SeqCst), 1); +} + +#[test] +fn once_bool_set() { + let cell = OnceBool::new(); + + assert!(cell.set(false).is_ok()); + assert_eq!(cell.get(), Some(false)); + + assert!(cell.set(true).is_err()); + assert_eq!(cell.get(), Some(false)); +} diff --git a/vendor/once_cell/tests/it/race_once_box.rs b/vendor/once_cell/tests/it/race_once_box.rs new file mode 100644 index 000000000..0bf3852d7 --- /dev/null +++ b/vendor/once_cell/tests/it/race_once_box.rs @@ -0,0 +1,145 @@ +#[cfg(feature = "std")] +use std::sync::Barrier; +use std::sync::{ + atomic::{AtomicUsize, Ordering::SeqCst}, + Arc, +}; + +use once_cell::race::OnceBox; + +#[derive(Default)] +struct Heap { + total: Arc<AtomicUsize>, +} + +#[derive(Debug)] +struct Pebble<T> { + val: T, + total: Arc<AtomicUsize>, +} + +impl<T> Drop for Pebble<T> { + fn drop(&mut self) { + self.total.fetch_sub(1, SeqCst); + } +} + +impl Heap { + fn total(&self) -> usize { + self.total.load(SeqCst) + } + fn new_pebble<T>(&self, val: T) -> Pebble<T> { + self.total.fetch_add(1, SeqCst); + Pebble { val, total: Arc::clone(&self.total) } + } +} + +#[cfg(feature = "std")] +#[test] +fn once_box_smoke_test() { + use std::thread::scope; + + let heap = Heap::default(); + let global_cnt = AtomicUsize::new(0); + let cell = OnceBox::new(); + let b = Barrier::new(128); + scope(|s| { + for _ in 0..128 { + s.spawn(|| { + let local_cnt = AtomicUsize::new(0); + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + b.wait(); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + }); + } + }); + assert!(cell.get().is_some()); + assert!(global_cnt.load(SeqCst) > 10); + + assert_eq!(heap.total(), 1); + drop(cell); + assert_eq!(heap.total(), 0); +} + +#[test] +fn once_box_set() { + let heap = Heap::default(); + let cell = OnceBox::new(); + assert!(cell.get().is_none()); + + assert!(cell.set(Box::new(heap.new_pebble("hello"))).is_ok()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + assert!(cell.set(Box::new(heap.new_pebble("world"))).is_err()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + drop(cell); + assert_eq!(heap.total(), 0); +} + +#[cfg(feature = "std")] +#[test] +fn once_box_first_wins() { + use std::thread::scope; + + let cell = OnceBox::new(); + let val1 = 92; + let val2 = 62; + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + Box::new(val1) + }); + assert_eq!(*r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + Box::new(val2) + }); + assert_eq!(*r2, val1); + }); + }); + + assert_eq!(cell.get(), Some(&val1)); +} + +#[test] +fn once_box_reentrant() { + let cell = OnceBox::new(); + let res = cell.get_or_init(|| { + cell.get_or_init(|| Box::new("hello".to_string())); + Box::new("world".to_string()) + }); + assert_eq!(res, "hello"); +} + +#[test] +fn once_box_default() { + struct Foo; + + let cell: OnceBox<Foo> = Default::default(); + assert!(cell.get().is_none()); +} diff --git a/vendor/once_cell/tests/it/sync_lazy.rs b/vendor/once_cell/tests/it/sync_lazy.rs new file mode 100644 index 000000000..44d70fa0c --- /dev/null +++ b/vendor/once_cell/tests/it/sync_lazy.rs @@ -0,0 +1,176 @@ +use std::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +use once_cell::sync::{Lazy, OnceCell}; + +#[test] +fn lazy_new() { + let called = AtomicUsize::new(0); + let x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + scope(|s| { + s.spawn(|| { + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + }); + }); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); +} + +#[test] +fn lazy_deref_mut() { + let called = AtomicUsize::new(0); + let mut x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.load(SeqCst), 1); +} + +#[test] +fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy<u32, _> = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy<std::sync::Mutex<Foo>> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn static_lazy() { + static XS: Lazy<Vec<i32>> = Lazy::new(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }); + scope(|s| { + s.spawn(|| { + assert_eq!(&*XS, &vec![1, 2, 3]); + }); + }); + assert_eq!(&*XS, &vec![1, 2, 3]); +} + +#[test] +fn static_lazy_via_fn() { + fn xs() -> &'static Vec<i32> { + static XS: OnceCell<Vec<i32>> = OnceCell::new(); + XS.get_or_init(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }) + } + assert_eq!(xs(), &vec![1, 2, 3]); +} + +#[test] +fn lazy_into_value() { + let l: Lazy<i32, _> = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); +} + +#[test] +fn lazy_poisoning() { + let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let lazy: Lazy<&String, _>; + { + let s = String::new(); + lazy = Lazy::new(|| &s); + _ = *lazy; + } +} + +#[test] +fn lazy_is_sync_send() { + fn assert_traits<T: Send + Sync>() {} + assert_traits::<Lazy<String>>(); +} diff --git a/vendor/once_cell/tests/it/sync_once_cell.rs b/vendor/once_cell/tests/it/sync_once_cell.rs new file mode 100644 index 000000000..252adeacf --- /dev/null +++ b/vendor/once_cell/tests/it/sync_once_cell.rs @@ -0,0 +1,309 @@ +use std::{ + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +#[cfg(feature = "std")] +use std::sync::Barrier; + +#[cfg(not(feature = "std"))] +use core::cell::Cell; + +use once_cell::sync::{Lazy, OnceCell}; + +#[test] +fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + scope(|s| { + s.spawn(|| { + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + }); + }); + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); +} + +#[test] +fn once_cell_with_value() { + static CELL: OnceCell<i32> = OnceCell::with_value(12); + assert_eq!(CELL.get(), Some(&12)); +} + +#[test] +fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); +} + +#[test] +fn once_cell_get_unchecked() { + let c = OnceCell::new(); + c.set(92).unwrap(); + unsafe { + assert_eq!(c.get_unchecked(), &92); + } +} + +#[test] +fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + scope(|s| { + s.spawn(|| { + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + }); + }); + assert_eq!(DROP_CNT.load(SeqCst), 1); +} + +#[test] +fn once_cell_drop_empty() { + let x = OnceCell::<String>::new(); + drop(x); +} + +#[test] +fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); +} + +#[test] +fn get_or_try_init() { + let cell: OnceCell<String> = OnceCell::new(); + assert!(cell.get().is_none()); + + let res = std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string())); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[cfg(feature = "std")] +#[test] +fn wait() { + let cell: OnceCell<String> = OnceCell::new(); + scope(|s| { + s.spawn(|| cell.set("hello".to_string())); + let greeting = cell.wait(); + assert_eq!(greeting, "hello") + }); +} + +#[cfg(feature = "std")] +#[test] +fn get_or_init_stress() { + let n_threads = if cfg!(miri) { 30 } else { 1_000 }; + let n_cells = if cfg!(miri) { 30 } else { 1_000 }; + let cells: Vec<_> = std::iter::repeat_with(|| (Barrier::new(n_threads), OnceCell::new())) + .take(n_cells) + .collect(); + scope(|s| { + for t in 0..n_threads { + let cells = &cells; + s.spawn(move || { + for (i, (b, s)) in cells.iter().enumerate() { + b.wait(); + let j = if t % 2 == 0 { s.wait() } else { s.get_or_init(|| i) }; + assert_eq!(*j, i); + } + }); + } + }); +} + +#[test] +fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); +} + +#[test] +fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::<String>::new() == OnceCell::new()); + assert!(OnceCell::<String>::new() != OnceCell::from("value".to_owned())); +} + +#[test] +fn into_inner() { + let cell: OnceCell<String> = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); +} + +#[test] +fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); + cell.set(vec!["hello", "world"]).unwrap(); + assert_eq!( + format!("{:#?}", cell), + r#"OnceCell( + [ + "hello", + "world", + ], +)"# + ); +} + +#[test] +#[cfg_attr(miri, ignore)] // miri doesn't support processes +#[cfg(feature = "std")] +fn reentrant_init() { + let examples_dir = { + let mut exe = std::env::current_exe().unwrap(); + exe.pop(); + exe.pop(); + exe.push("examples"); + exe + }; + let bin = examples_dir + .join("reentrant_init_deadlocks") + .with_extension(std::env::consts::EXE_EXTENSION); + let mut guard = Guard { child: std::process::Command::new(bin).spawn().unwrap() }; + std::thread::sleep(std::time::Duration::from_secs(2)); + let status = guard.child.try_wait().unwrap(); + assert!(status.is_none()); + + struct Guard { + child: std::process::Child, + } + + impl Drop for Guard { + fn drop(&mut self) { + let _ = self.child.kill(); + } + } +} + +#[cfg(not(feature = "std"))] +#[test] +#[should_panic(expected = "reentrant init")] +fn reentrant_init() { + let x: OnceCell<Box<i32>> = OnceCell::new(); + let dangling_ref: Cell<Option<&i32>> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); +} + +#[test] +fn eval_once_macro() { + macro_rules! eval_once { + (|| -> $ty:ty { + $($body:tt)* + }) => {{ + static ONCE_CELL: OnceCell<$ty> = OnceCell::new(); + fn init() -> $ty { + $($body)* + } + ONCE_CELL.get_or_init(init) + }}; + } + + let fib: &'static Vec<i32> = eval_once! { + || -> Vec<i32> { + let mut res = vec![1, 1]; + for i in 0..10 { + let next = res[i] + res[i + 1]; + res.push(next); + } + res + } + }; + assert_eq!(fib[5], 8) +} + +#[test] +fn once_cell_does_not_leak_partially_constructed_boxes() { + let n_tries = if cfg!(miri) { 10 } else { 100 }; + let n_readers = 10; + let n_writers = 3; + const MSG: &str = "Hello, World"; + + for _ in 0..n_tries { + let cell: OnceCell<String> = OnceCell::new(); + scope(|scope| { + for _ in 0..n_readers { + scope.spawn(|| loop { + if let Some(msg) = cell.get() { + assert_eq!(msg, MSG); + break; + } + }); + } + for _ in 0..n_writers { + let _ = scope.spawn(|| cell.set(MSG.to_owned())); + } + }); + } +} + +#[cfg(feature = "std")] +#[test] +fn get_does_not_block() { + let cell = OnceCell::new(); + let barrier = Barrier::new(2); + scope(|scope| { + scope.spawn(|| { + cell.get_or_init(|| { + barrier.wait(); + barrier.wait(); + "hello".to_string() + }); + }); + barrier.wait(); + assert_eq!(cell.get(), None); + barrier.wait(); + }); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} + +#[test] +fn once_cell_is_sync_send() { + fn assert_traits<T: Send + Sync>() {} + assert_traits::<OnceCell<String>>(); + assert_traits::<Lazy<String>>(); +} diff --git a/vendor/once_cell/tests/it/unsync_lazy.rs b/vendor/once_cell/tests/it/unsync_lazy.rs new file mode 100644 index 000000000..0c308cab0 --- /dev/null +++ b/vendor/once_cell/tests/it/unsync_lazy.rs @@ -0,0 +1,134 @@ +use core::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, +}; + +use once_cell::unsync::Lazy; + +#[test] +fn lazy_new() { + let called = Cell::new(0); + let x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_deref_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy<u32, _> = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy<std::sync::Mutex<Foo>> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn lazy_into_value() { + let l: Lazy<i32, _> = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); +} + +#[test] +#[cfg(feature = "std")] +fn lazy_poisoning() { + let x: Lazy<String> = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let lazy: Lazy<&String, _>; + { + let s = String::new(); + lazy = Lazy::new(|| &s); + _ = *lazy; + } +} diff --git a/vendor/once_cell/tests/it/unsync_once_cell.rs b/vendor/once_cell/tests/it/unsync_once_cell.rs new file mode 100644 index 000000000..124cc3e6d --- /dev/null +++ b/vendor/once_cell/tests/it/unsync_once_cell.rs @@ -0,0 +1,154 @@ +use core::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, +}; + +use once_cell::unsync::OnceCell; + +#[test] +fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); +} + +#[test] +fn once_cell_with_value() { + const CELL: OnceCell<i32> = OnceCell::with_value(12); + let cell = CELL; + assert_eq!(cell.get(), Some(&12)); +} + +#[test] +fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); +} + +#[test] +fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + assert_eq!(DROP_CNT.load(SeqCst), 1); +} + +#[test] +fn once_cell_drop_empty() { + let x = OnceCell::<String>::new(); + drop(x); +} + +#[test] +fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); +} + +#[test] +fn get_or_try_init() { + let cell: OnceCell<String> = OnceCell::new(); + assert!(cell.get().is_none()); + + let res = std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string())); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[test] +fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); +} + +#[test] +fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::<String>::new() == OnceCell::new()); + assert!(OnceCell::<String>::new() != OnceCell::from("value".to_owned())); +} + +#[test] +fn into_inner() { + let cell: OnceCell<String> = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); +} + +#[test] +fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); + cell.set(vec!["hello", "world"]).unwrap(); + assert_eq!( + format!("{:#?}", cell), + r#"OnceCell( + [ + "hello", + "world", + ], +)"# + ); +} + +#[test] +#[should_panic(expected = "reentrant init")] +fn reentrant_init() { + let x: OnceCell<Box<i32>> = OnceCell::new(); + let dangling_ref: Cell<Option<&i32>> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); +} + +#[test] +fn aliasing_in_get() { + let x = OnceCell::new(); + x.set(42).unwrap(); + let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option<T>` --+ + let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option<T>` | + println!("{}", at_x); // <------- up until here ---------------------------+ +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} |