Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lazy initialization primitives to std #68198

Closed
wants to merge 6 commits into from
Closed

Add lazy initialization primitives to std #68198

wants to merge 6 commits into from

Conversation

KodrAus
Copy link
Contributor

@KodrAus KodrAus commented Jan 14, 2020

cc @matklad @pitdicker

Current RFC: rust-lang/rfcs#2788

This PR picks up @matklad's initial std implementation, based on their once_cell crate, and shifts a few things around, adds unstability attributes, and some docs.

It adds the following new unstable APIs:

crate core {
    pub mod lazy {
        pub struct OnceCell<T>;

        impl<T> Default for OnceCell<T> {}
        impl<T: Debug> Debug for OnceCell<T> {}
        impl<T: Clone> Clone for OnceCell<T> {}
        impl<T: PartialEq> PartialEq for OnceCell<T> {}
        impl<T: Eq> Eq for OnceCell<T> {}
        impl<T> From<T> for OnceCell<T> {}

        impl<T> OnceCell<T> {
            pub const fn new() -> OnceCell<T> {}
            pub fn get(&self) -> Option<&T> {}
            pub fn get_mut(&mut self) -> Option<&mut T> {}
            pub fn set(&self, value: T) -> Result<(), T> {}
            pub fn get_or_init<F>(&self, f: F) -> &T where F: FnOnce() -> T {}
            pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E> {}
            pub fn into_inner(self) -> Option<T> {}
        }

        pub struct Lazy<T, F = fn() -> T>;

        impl<T: Debug, F: Debug> Debug for Lazy<T, F> {}
        impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { type Target = T; }
        impl<T: Default> Default for Lazy<T> {}

        impl<T, F> Lazy<T, F> {
            pub const fn new(init: F) -> Lazy<T, F> {}
        }

        impl<T, F: FnOnce() -> T> Lazy<T, F> {
            pub fn force(this: &Lazy<T, F>) -> &T {}
        }
    }
}

crate std {
    pub mod lazy {
        pub use core::lazy::*;

        pub struct SyncOnceCell<T>;

        unsafe impl<T: Sync + Send> Sync for SyncOnceCell<T> {}
        unsafe impl<T: Send> Send for SyncOnceCell<T> {}
        impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
        impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}

        impl<T> Default for SyncOnceCell<T> {}
        impl<T: Debug> Debug for SyncOnceCell<T> {}
        impl<T: Clone> Clone for SyncOnceCell<T> {}
        impl<T> From<T> for SyncOnceCell<T> {}
        impl<T: PartialEq> PartialEq for SyncOnceCell<T> {}
        impl<T: Eq> Eq for SyncOnceCell<T> {}

        impl<T> SyncOnceCell<T> {
            pub const fn new() -> SyncOnceCell<T> {}
            pub fn get(&self) -> Option<&T> {}
            pub fn get_mut(&mut self) -> Option<&mut T> {}
            pub fn set(&self, value: T) -> Result<(), T> {}
            pub fn get_or_init<F>(&self, f: F) -> &T where F: FnOnce() -> T {}
            pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E> {}
            pub fn into_inner(self) -> Option<T> {}

        }

        pub struct SyncLazy<T, F = fn() -> T>;

        unsafe impl<T, F: Send> Sync for SyncLazy<T, F> where Once<T>: Sync {}
        impl<T, F: RefUnwindSafe> RefUnwindSafe for SyncLazy<T, F> where Once<T>: RefUnwindSafe {}

        impl<T: Debug, F: Debug> Debug for SyncLazy<T, F> {}
        impl<T, F: FnOnce() -> T> Deref for SyncLazy<T, F> {}
        impl<T: Default> Default for SyncLazy<T> {}

        impl<T, F> SyncLazy<T, F> {
            pub const fn new(f: F) -> SyncLazy<T, F> {}
        }

        impl<T, F: FnOnce() -> T> SyncLazy<T, F> {
            pub fn force(this: &SyncLazy<T, F>) -> &T {}
        }
    }
}

The implementation is based on once_cell.

Open questions

Merge blockers

  • Panicking behaviour of SyncOnceCell.
  • Synchronization guarantees for sync flavor (acquire or consume?).

Others

  • Should OnceCell impl CoerceUnsized?
  • Module layout and item naming.
  • Method naming (get_or_init or get_or_set_with?).
  • Replace std::io::lazy::Lazy.
  • Optimize the size of SyncLazy.

Any of these questions that aren't resolved in this PR will get copied into a tracking issue

@rust-highfive
Copy link
Collaborator

r? @cramertj

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 14, 2020
@KodrAus KodrAus added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 14, 2020
@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 14, 2020

I believe the implementation is exactly what's in once_cell

Ah this is actually not totally true. I replaced the Option<T> in lazy::Once with MaybeUninit<T>.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-7 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2020-01-14T04:02:35.7088425Z ##[command]git remote add origin https://github.com/rust-lang/rust
2020-01-14T04:02:35.8179801Z ##[command]git config gc.auto 0
2020-01-14T04:02:35.8266422Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2020-01-14T04:02:35.8331053Z ##[command]git config --get-all http.proxy
2020-01-14T04:02:35.8472013Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/68198/merge:refs/remotes/pull/68198/merge

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-7 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2020-01-14T05:47:16.7147101Z ##[command]git remote add origin https://github.com/rust-lang/rust
2020-01-14T05:47:16.7242590Z ##[command]git config gc.auto 0
2020-01-14T05:47:16.7325615Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2020-01-14T05:47:16.7386228Z ##[command]git config --get-all http.proxy
2020-01-14T05:47:16.7535452Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/68198/merge:refs/remotes/pull/68198/merge
---
2020-01-14T06:42:25.3941453Z ........................................i...............i........................................... 4900/9518
2020-01-14T06:42:34.2358026Z .................................................................................................... 5000/9518
2020-01-14T06:42:40.2498447Z ...................................................................................i................ 5100/9518
2020-01-14T06:42:45.4523326Z .................................................................................................... 5200/9518
2020-01-14T06:42:55.3109331Z ......................................................ii.ii...........i............................. 5300/9518
2020-01-14T06:43:04.0423980Z .................................................................................................... 5500/9518
2020-01-14T06:43:13.6320404Z .................................................................................................... 5600/9518
2020-01-14T06:43:19.8939722Z .......................................i............................................................ 5700/9518
2020-01-14T06:43:25.9777889Z .................................................................................................... 5800/9518
2020-01-14T06:43:25.9777889Z .................................................................................................... 5800/9518
2020-01-14T06:43:36.1329838Z .................................................................................................... 5900/9518
2020-01-14T06:43:45.5234326Z ..............................ii...i..ii............i............................................... 6000/9518
2020-01-14T06:44:03.6315746Z .................................................................................................... 6200/9518
2020-01-14T06:44:11.6975874Z .................................................................................................... 6300/9518
2020-01-14T06:44:11.6975874Z .................................................................................................... 6300/9518
2020-01-14T06:44:23.4643768Z ..........................................................i..ii..................................... 6400/9518
2020-01-14T06:44:49.6990545Z .................................................................................................... 6600/9518
2020-01-14T06:44:51.7690140Z ..................................i................................................................. 6700/9518
2020-01-14T06:44:53.8667628Z .................................................................................................... 6800/9518
2020-01-14T06:44:56.2445437Z ..................................i................................................................. 6900/9518
---
2020-01-14T06:46:29.7226571Z .................................................................................................... 7500/9518
2020-01-14T06:46:34.0797873Z .................................................................................................... 7600/9518
2020-01-14T06:46:39.9712305Z .................................................................................................... 7700/9518
2020-01-14T06:46:46.9500692Z .................................................................................................... 7800/9518
2020-01-14T06:46:56.0879283Z ...................................................................................iiii............. 7900/9518
2020-01-14T06:47:12.1908178Z .................i......i........................................................................... 8100/9518
2020-01-14T06:47:17.1935434Z .................................................................................................... 8200/9518
2020-01-14T06:47:29.8694989Z .................................................................................................... 8300/9518
2020-01-14T06:47:39.4521878Z .................................................................................................... 8400/9518
---
2020-01-14T06:49:58.3604149Z  finished in 6.670
2020-01-14T06:49:58.3782594Z Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:49:58.5781215Z 
2020-01-14T06:49:58.5784929Z running 166 tests
2020-01-14T06:50:01.5692132Z iiii......i........ii..iiii...i....i...........i............i..i..................i....i............ 100/166
2020-01-14T06:50:03.8129356Z i.i.i...iii..iiiiiii.......................iii............ii......
2020-01-14T06:50:03.8131122Z 
2020-01-14T06:50:03.8134607Z  finished in 5.435
2020-01-14T06:50:03.8319013Z Check compiletest suite=codegen-units mode=codegen-units (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:50:03.9984582Z 
---
2020-01-14T06:50:05.9602538Z  finished in 2.128
2020-01-14T06:50:05.9785758Z Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:50:06.1306132Z 
2020-01-14T06:50:06.1309122Z running 9 tests
2020-01-14T06:50:06.1312217Z iiiiiiiii
2020-01-14T06:50:06.1312900Z 
2020-01-14T06:50:06.1313036Z  finished in 0.152
2020-01-14T06:50:06.1500563Z Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:50:06.3467661Z 
---
2020-01-14T06:50:26.8964453Z  finished in 20.746
2020-01-14T06:50:26.9174944Z Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:50:27.1238847Z 
2020-01-14T06:50:27.1239327Z running 116 tests
2020-01-14T06:50:50.8069363Z .iiiii..i.....i..i...i..i.i.i..i..i..ii....i.i....ii..........iiii..........i.....i..i.......ii.i.ii 100/116
2020-01-14T06:50:53.9614155Z .....iiii.....ii
2020-01-14T06:50:53.9615471Z 
2020-01-14T06:50:53.9615762Z  finished in 27.044
2020-01-14T06:50:53.9620784Z Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T06:50:53.9622870Z Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
---
2020-01-14T07:03:10.9176005Z 
2020-01-14T07:03:10.9176945Z    Doc-tests core
2020-01-14T07:03:15.3099880Z 
2020-01-14T07:03:15.3102686Z running 2450 tests
2020-01-14T07:03:24.3544634Z ......iiiii......................................................................................... 100/2450
2020-01-14T07:03:33.0089130Z ..........................................................................................ii........ 200/2450
2020-01-14T07:03:52.3278509Z ........................i........................................................................... 400/2450
2020-01-14T07:03:52.3278509Z ........................i........................................................................... 400/2450
2020-01-14T07:04:01.6719415Z .........................................................................i..i..................iiii. 500/2450
2020-01-14T07:04:17.3165579Z .................................................................................................... 700/2450
2020-01-14T07:04:25.4608737Z .................................................................................................... 800/2450
2020-01-14T07:04:33.5743793Z .................................................................................................... 900/2450
2020-01-14T07:04:41.9990210Z .................................................................................................... 1000/2450
---
2020-01-14T07:08:09.5391330Z 
2020-01-14T07:08:09.5391605Z running 1016 tests
2020-01-14T07:08:26.8296600Z i................................................................................................... 100/1016
2020-01-14T07:08:36.2531441Z .................................................................................................... 200/1016
2020-01-14T07:08:42.8936070Z ..................iii......i......i...i......i...................................................... 300/1016
2020-01-14T07:08:47.8914892Z .................................................................................................... 400/1016
2020-01-14T07:08:54.7061701Z ..........................................i..i............................FFFF..F...............ii.. 500/1016
2020-01-14T07:09:07.4154431Z .................................................................................................... 700/1016
2020-01-14T07:09:07.4154431Z .................................................................................................... 700/1016
2020-01-14T07:09:14.1238938Z ..........................................iiii...................................................... 800/1016
2020-01-14T07:09:28.0502328Z .................................................................................................... 900/1016
2020-01-14T07:09:34.7242509Z ................................................................iiii................................ 1000/1016
2020-01-14T07:09:35.4018838Z failures:
2020-01-14T07:09:35.4018982Z 
2020-01-14T07:09:35.4019671Z ---- lazy.rs - lazy (line 137) stdout ----
2020-01-14T07:09:35.4019904Z error: unused macro definition
2020-01-14T07:09:35.4019904Z error: unused macro definition
2020-01-14T07:09:35.4020340Z  --> lazy.rs:138:1
2020-01-14T07:09:35.4020545Z   |
2020-01-14T07:09:35.4020733Z 4 | / macro_rules! regex {
2020-01-14T07:09:35.4020817Z 5 | |     ($re:literal $(,)?) => {{
2020-01-14T07:09:35.4021047Z 6 | |         static RE: std::lazy::Once<regex::Regex> = std::lazy::Once::new();
2020-01-14T07:09:35.4021117Z 7 | |         RE.get_or_init(|| regex::Regex::new($re).unwrap())
2020-01-14T07:09:35.4021577Z 9 | | }
2020-01-14T07:09:35.4021722Z   | |_^
2020-01-14T07:09:35.4021775Z   |
2020-01-14T07:09:35.4021854Z note: lint level defined here
---
2020-01-14T07:09:35.4023420Z ---- lazy.rs - lazy (line 17) stdout ----
2020-01-14T07:09:35.4023603Z error: unused import: `io`
2020-01-14T07:09:35.4023881Z  --> lazy.rs:20:16
2020-01-14T07:09:35.4023923Z   |
2020-01-14T07:09:35.4023959Z 5 | use std::{env, io};
2020-01-14T07:09:35.4024198Z   |
2020-01-14T07:09:35.4024371Z note: lint level defined here
2020-01-14T07:09:35.4024640Z  --> lazy.rs:16:9
2020-01-14T07:09:35.4024831Z   |
---
2020-01-14T07:09:35.4027387Z error: aborting due to previous error
2020-01-14T07:09:35.4027697Z 
2020-01-14T07:09:35.4028234Z For more information about this error, try `rustc --explain E0432`.
2020-01-14T07:09:35.4028643Z Couldn't compile the test.
2020-01-14T07:09:35.4029058Z ---- lazy.rs - lazy::Once (line 191) stdout ----
2020-01-14T07:09:35.4029364Z error[E0433]: failed to resolve: use of undeclared type or module `OnceCell`
2020-01-14T07:09:35.4029773Z  --> lazy.rs:196:33
2020-01-14T07:09:35.4029822Z   |
2020-01-14T07:09:35.4030021Z 8 | static CELL: OnceCell<String> = OnceCell::new();
2020-01-14T07:09:35.4030136Z   |                                 ^^^^^^^^ use of undeclared type or module `OnceCell`
2020-01-14T07:09:35.4030484Z error[E0412]: cannot find type `OnceCell` in this scope
2020-01-14T07:09:35.4030912Z  --> lazy.rs:196:14
2020-01-14T07:09:35.4031131Z   |
2020-01-14T07:09:35.4031131Z   |
2020-01-14T07:09:35.4031272Z 8 | static CELL: OnceCell<String> = OnceCell::new();
2020-01-14T07:09:35.4031501Z   |
2020-01-14T07:09:35.4031750Z help: possible candidates are found in other modules, you can import them into scope
2020-01-14T07:09:35.4031834Z   |
2020-01-14T07:09:35.4031834Z   |
2020-01-14T07:09:35.4031896Z 5 | use core::cell::OnceCell;
2020-01-14T07:09:35.4032036Z 5 | use std::cell::OnceCell;
2020-01-14T07:09:35.4032076Z   |
2020-01-14T07:09:35.4032102Z 
2020-01-14T07:09:35.4032256Z error: unused import: `std::lazy::Once`
2020-01-14T07:09:35.4032256Z error: unused import: `std::lazy::Once`
2020-01-14T07:09:35.4034120Z  --> lazy.rs:194:5
2020-01-14T07:09:35.4034342Z   |
2020-01-14T07:09:35.4034579Z 6 | use std::lazy::Once;
2020-01-14T07:09:35.4034689Z   |
2020-01-14T07:09:35.4034730Z note: lint level defined here
2020-01-14T07:09:35.4035028Z  --> lazy.rs:189:9
2020-01-14T07:09:35.4035072Z   |
---
2020-01-14T07:09:35.4241327Z   local time: Tue Jan 14 07:09:35 UTC 2020
2020-01-14T07:09:35.7100080Z   network time: Tue, 14 Jan 2020 07:09:35 GMT
2020-01-14T07:09:35.7104405Z == end clock drift check ==
2020-01-14T07:09:36.0809638Z 
2020-01-14T07:09:36.0878124Z ##[error]Bash exited with code '1'.
2020-01-14T07:09:36.0910953Z ##[section]Starting: Checkout
2020-01-14T07:09:36.0912908Z ==============================================================================
2020-01-14T07:09:36.0913159Z Task         : Get sources
2020-01-14T07:09:36.0913204Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

src/libcore/cell.rs Outdated Show resolved Hide resolved
@CryZe
Copy link
Contributor

CryZe commented Jan 14, 2020

Also the RFC seems to have Lazy and Once in the sync module, which seems to make a lot more sense to me. Having not read the RFC before seeing this PR, I've been really confused by what the difference between the core and std versions of the Lazy and Once types are.

Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

There's a bunch of tests here, and most of them could be ported to std.

I am personally not too thrilled about the naming scheme proposed in the PR. At a glance, I can't tell whats the difference between lazy::OnceCell and cell::OnceCell, as nothing says that the first one is sync.

I've also thought about this, seemingly minimally disagreeable, scheme:

std::{
  lazy::{
    OnceCell, Lazy,
    SyncOnceCell, SyncLazy,
  }
}

Also, a specific unresolved question which maybe makes sense to attack first is poisoning. Once we figure out poisoning, we will be able to share the implementaion betwen Once and OnceCell (in particular, we can share the impl even if Once is release/acquire, and OnceCell is release/consume).

src/libstd/lazy.rs Outdated Show resolved Hide resolved
@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 14, 2020

Also the RFC seems to have Lazy and Once in the sync module, which seems to make a lot more sense to me.

Not putting the sync variants in the sync module is based on trying to avoid growing it more.

I can't tell whats the difference between lazy::OnceCell and cell::OnceCell, as nothing says that the first one is sync.

Ah, the scheme used at the moment in this PR is core::cell::OnceCell + core::cell::LazyCell for unsync and std::lazy::Once + std::lazy::Lazy for sync. So what's in cell remains consistent with other cell types, and what's in lazy is the more universally useful sync types.

Personally, I prefer the Cell suffix over the Sync prefix for differentiating the sync and unsync implementations, but I haven't got any strong argument against the Sync prefix, and will try not to pull discussion that belongs in the RFC into this PR. If we've got some loose consensus on SyncOnceCell + SyncLazy, or any other scheme, then I'll use that 🙂

There's a bunch of tests here, and most of them could be ported to std.

Great! I'll pull them in 😄

Copy link
Contributor

@pitdicker pitdicker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for doing the work, and for notifying me 😄 !

2 small comments.

state_and_queue: AtomicUsize,
_marker: PhantomData<*mut Waiter>,
// Whether or not the value is initialized is tracked by `state_and_queue`.
value: UnsafeCell<MaybeUninit<T>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you implement Drop in combination with MaybeUninit? Can you compare it with matklad/once_cell#72?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah great point! When you made this comment I wasn't handling Drop at all. I've since pulled in your implementation from once_cell 👍

src/libstd/lazy.rs Outdated Show resolved Hide resolved
@CryZe
Copy link
Contributor

CryZe commented Jan 14, 2020

Not putting the sync variants in the sync module is based on trying to avoid growing it more.

That does not seem well motivated. Instead you are just growing the base module of std more with that, which already is getting quite large, while the sync module is much smaller. If the unsync variant is in the cell module, the sync variant should be in the sync module. I'd accept an alternative where all are in the lazy module, but then the distinction between the sync and unsync variants needs to be much clearer and can't compare with other Cells as much as it currently does (cause why is it just another Cell type but not in the cell module?)

@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 14, 2020

That does not seem well motivated. Instead you are just growing the base module of std more with that, which already is getting quite large, while the sync module is much smaller.

I think it’s less the size of the sync module (and sync is still quite a sizeable module) and more its scope that motivates a “don’t put it in sync” policy by default. It’s a bag of locks, atomics, barriers and channels. That doesn’t mean it’s not an appropriate place, just not where I think we should be looking by default.

To keep things moving I’ll refactor back to the original layout:

crate core {
    pub mod lazy {
        pub struct OnceCell;
        pub struct Lazy;
    }
}

crate std {
    pub mod lazy {
        pub use core::lazy::*;

        pub struct SyncOnceCell;
        pub struct SyncLazy;
    }
}

and we can focus on other implementation questions. I think there are still open questions surfaced by this API we should answer eventually, like what a cell actually is, and whether SyncOnceCell is one, but items can be shifted around.

Does that seem reasonable?

@matklad
Copy link
Member

matklad commented Jan 14, 2020

That does not seem well motivated.

See also: rust-lang/rfcs#2788 (comment). I personally do think that std::sync is unfortunately a bit of a kitchen sink right now.

@matklad
Copy link
Member

matklad commented Jan 14, 2020

Something which occurred to me just now: we can implement

impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F>

as well as

impl OnceCell<T> {
    pub fn get_or_init_mut<F>(&mut self, f: F) -> &mut T
}

!

I think this would be sound, and I have a use case for DerefMut Lazy in rust-analyzer right now!

EDIT: yup, DerefMut just works: matklad/once_cell#86

@pitdicker
Copy link
Contributor

Agreed on DerefMut, the argument for why it is safe is the same as for as_mut.

I am not sure what your thoughts are with get_or_init_mut. But maybe it is best to not discuss extensions to the API in this PR, as I think you suggested above. Do you want to open an issue

@matklad
Copy link
Member

matklad commented Jan 14, 2020

Do you want to open an issue

@KodrAus yeah, I think it might be in general useful to open a tracking issue with checkboxes for all of the unresolved questions

@cramertj
Copy link
Member

r? @sfackler

@rust-highfive rust-highfive assigned sfackler and unassigned cramertj Jan 14, 2020
@rust-highfive
Copy link
Collaborator

The job mingw-check of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2020-01-14T21:26:01.8773583Z ##[command]git remote add origin https://github.com/rust-lang/rust
2020-01-14T21:26:01.8854327Z ##[command]git config gc.auto 0
2020-01-14T21:26:01.8938106Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2020-01-14T21:26:01.8985603Z ##[command]git config --get-all http.proxy
2020-01-14T21:26:01.9129514Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/68198/merge:refs/remotes/pull/68198/merge
---
2020-01-14T21:30:18.3981027Z     |
2020-01-14T21:30:18.3981308Z 460 |         ManuallyDrop::new(self);
2020-01-14T21:30:18.3981685Z     |         ^^^^^^^^^^^^ use of undeclared type or module `ManuallyDrop`
2020-01-14T21:30:18.3985641Z 
2020-01-14T21:30:20.0019123Z error[E0609]: no field `0` on type `&mut lazy::Once<T>`
2020-01-14T21:30:20.0019462Z    --> src/libstd/lazy.rs:474:17
2020-01-14T21:30:20.0019953Z 474 |         if self.0.is_initialized() {
2020-01-14T21:30:20.0020532Z     |                 ^ unknown field
2020-01-14T21:30:20.0020767Z     |
2020-01-14T21:30:20.0020767Z     |
2020-01-14T21:30:20.0021134Z     = note: available fields are: `state_and_queue`, `_marker`, `value`
2020-01-14T21:30:20.4741862Z error: aborting due to 2 previous errors
2020-01-14T21:30:20.4741975Z 
2020-01-14T21:30:20.4742251Z Some errors have detailed explanations: E0433, E0609.
2020-01-14T21:30:20.4742510Z For more information about an error, try `rustc --explain E0433`.
---
2020-01-14T21:30:20.4938859Z   local time: Tue Jan 14 21:30:20 UTC 2020
2020-01-14T21:30:20.5332662Z   network time: Tue, 14 Jan 2020 21:30:20 GMT
2020-01-14T21:30:20.5332785Z == end clock drift check ==
2020-01-14T21:30:21.4880527Z 
2020-01-14T21:30:21.4977401Z ##[error]Bash exited with code '1'.
2020-01-14T21:30:21.5007258Z ##[section]Starting: Checkout
2020-01-14T21:30:21.5008941Z ==============================================================================
2020-01-14T21:30:21.5009000Z Task         : Get sources
2020-01-14T21:30:21.5009072Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 14, 2020

@matklad Ah I think our lines might’ve crossed, but maybe to try keep the number of open channels lower we could try work through some of those implementation questions here and then open a tracking issue with a link to the RFC and any remaining open questions or non-blocking ones that might come up from a FCP before merging?

@matklad
Copy link
Member

matklad commented Jan 14, 2020

Ah, I see that the PR description has open questions section, missed it at first. I've added a couple

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-7 of your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
2020-01-14T22:14:23.9716672Z ##[command]git remote add origin https://github.com/rust-lang/rust
2020-01-14T22:14:23.9728825Z ##[command]git config gc.auto 0
2020-01-14T22:14:23.9747564Z ##[command]git config --get-all http.https://github.com/rust-lang/rust.extraheader
2020-01-14T22:14:23.9750957Z ##[command]git config --get-all http.proxy
2020-01-14T22:14:23.9886869Z ##[command]git -c http.extraheader="AUTHORIZATION: basic ***" fetch --force --tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/*:refs/remotes/origin/* +refs/pull/68198/merge:refs/remotes/pull/68198/merge
---
2020-01-14T23:09:13.7874203Z .................................................................................................... 1600/9519
2020-01-14T23:09:19.3359116Z .................................................................................................... 1700/9519
2020-01-14T23:09:29.1463280Z .................................................................................................... 1800/9519
2020-01-14T23:09:38.4682839Z ........i........................................................................................... 1900/9519
2020-01-14T23:09:45.7026035Z ...................................................................................................i 2000/9519
2020-01-14T23:10:02.6589463Z iiii................................................................................................ 2100/9519
2020-01-14T23:10:11.2374822Z .................................................................................................... 2300/9519
2020-01-14T23:10:13.7269896Z .................................................................................................... 2400/9519
2020-01-14T23:10:19.7039178Z .................................................................................................... 2500/9519
2020-01-14T23:10:40.3476566Z .................................................................................................... 2600/9519
---
2020-01-14T23:13:28.2418191Z .........................................i...............i.......................................... 4900/9519
2020-01-14T23:13:38.0197759Z .................................................................................................... 5000/9519
2020-01-14T23:13:44.7028565Z ....................................................................................i............... 5100/9519
2020-01-14T23:13:50.2876305Z .................................................................................................... 5200/9519
2020-01-14T23:14:00.8752300Z .......................................................ii.ii...........i............................ 5300/9519
2020-01-14T23:14:10.1011412Z .................................................................................................... 5500/9519
2020-01-14T23:14:20.4823816Z .................................................................................................... 5600/9519
2020-01-14T23:14:27.0351080Z ........................................i........................................................... 5700/9519
2020-01-14T23:14:33.8670033Z .................................................................................................... 5800/9519
2020-01-14T23:14:33.8670033Z .................................................................................................... 5800/9519
2020-01-14T23:14:44.8825452Z .................................................................................................... 5900/9519
2020-01-14T23:14:54.5489943Z ...............................ii...i..ii...........i............................................... 6000/9519
2020-01-14T23:15:13.5694318Z .................................................................................................... 6200/9519
2020-01-14T23:15:21.9211426Z .................................................................................................... 6300/9519
2020-01-14T23:15:21.9211426Z .................................................................................................... 6300/9519
2020-01-14T23:15:31.9797650Z ...........................................................i..ii.................................... 6400/9519
2020-01-14T23:15:59.7685662Z .................................................................................................... 6600/9519
2020-01-14T23:16:01.9695403Z ...................................i................................................................ 6700/9519
2020-01-14T23:16:04.2185532Z .................................................................................................... 6800/9519
2020-01-14T23:16:06.7423991Z ...................................i................................................................ 6900/9519
---
2020-01-14T23:17:45.6236387Z .................................................................................................... 7500/9519
2020-01-14T23:17:49.7943061Z .................................................................................................... 7600/9519
2020-01-14T23:17:55.8407017Z .................................................................................................... 7700/9519
2020-01-14T23:18:02.8731630Z .................................................................................................... 7800/9519
2020-01-14T23:18:12.8338818Z ....................................................................................iiii............ 7900/9519
2020-01-14T23:18:30.2699291Z ..................i......i.......................................................................... 8100/9519
2020-01-14T23:18:35.6264558Z .................................................................................................... 8200/9519
2020-01-14T23:18:49.1914777Z .................................................................................................... 8300/9519
2020-01-14T23:18:59.1530695Z .................................................................................................... 8400/9519
---
2020-01-14T23:21:20.0090288Z  finished in 7.218
2020-01-14T23:21:20.0314244Z Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:21:20.2324298Z 
2020-01-14T23:21:20.2324534Z running 166 tests
2020-01-14T23:21:23.4376472Z iiii......i........ii..iiii...i....i...........i............i..i..................i....i............ 100/166
2020-01-14T23:21:25.8246344Z i.i.i...iii..iiiiiii.......................iii............ii......
2020-01-14T23:21:25.8248251Z 
2020-01-14T23:21:25.8248371Z  finished in 5.793
2020-01-14T23:21:25.8459432Z Check compiletest suite=codegen-units mode=codegen-units (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:21:26.0204467Z 
---
2020-01-14T23:21:28.1422650Z  finished in 2.296
2020-01-14T23:21:28.1640321Z Check compiletest suite=assembly mode=assembly (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:21:28.3325292Z 
2020-01-14T23:21:28.3325665Z running 9 tests
2020-01-14T23:21:28.3326819Z iiiiiiiii
2020-01-14T23:21:28.3327263Z 
2020-01-14T23:21:28.3331887Z  finished in 0.169
2020-01-14T23:21:28.3537764Z Check compiletest suite=incremental mode=incremental (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:21:28.5521847Z 
---
2020-01-14T23:21:49.6716984Z  finished in 21.318
2020-01-14T23:21:50.1923742Z Check compiletest suite=debuginfo mode=debuginfo-gdb+lldb (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:21:50.5452130Z 
2020-01-14T23:21:50.5452440Z running 116 tests
2020-01-14T23:22:16.5927770Z .iiiii..i.....i..i...i..i.i.i..i..i..ii....i.i....ii..........iiii..........i.....i..i.......ii.i.ii 100/116
2020-01-14T23:22:20.2159276Z .....iiii.....ii
2020-01-14T23:22:20.2160527Z 
2020-01-14T23:22:20.2167063Z  finished in 30.024
2020-01-14T23:22:20.2170052Z Uplifting stage1 rustc (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-01-14T23:22:20.2170400Z Copying stage2 rustc from stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
---
2020-01-14T23:34:50.4061514Z 
2020-01-14T23:34:50.4062388Z    Doc-tests core
2020-01-14T23:34:54.7637154Z 
2020-01-14T23:34:54.7637825Z running 2450 tests
2020-01-14T23:35:03.9614782Z ......iiiii......................................................................................... 100/2450
2020-01-14T23:35:13.0055746Z ..........................................................................................ii........ 200/2450
2020-01-14T23:35:33.2736289Z ........................i........................................................................... 400/2450
2020-01-14T23:35:33.2736289Z ........................i........................................................................... 400/2450
2020-01-14T23:35:42.8887986Z .........................................................................i..i..................iiii. 500/2450
2020-01-14T23:35:59.1785940Z .................................................................................................... 700/2450
2020-01-14T23:36:06.9133043Z .................................................................................................... 800/2450
2020-01-14T23:36:15.5573075Z .................................................................................................... 900/2450
2020-01-14T23:36:24.7469725Z .................................................................................................... 1000/2450
---
2020-01-14T23:39:59.5325596Z .................................thread '<unnamed>' panicked at 'explicit panic', src/libstd/thread/mod.rs:1573:37
2020-01-14T23:40:00.1429858Z ...........thread '<unnamed>' panicked at 'Box<Any>', src/libstd/thread/mod.rs:1708:13
2020-01-14T23:40:00.1432821Z .thread '<unnamed>' panicked at 'owned string', src/libstd/thread/mod.rs:1692:13
2020-01-14T23:40:00.1433183Z thread '<unnamed>' panicked at 'static string', src/libstd/thread/mod.rs:1676:13
2020-01-14T23:40:00.1433403Z thread '<unnamed>' panicked at 'Box<Any>...', src/libstd/thread/mod.rs:1727:37
2020-01-14T23:40:05.6517498Z test result: ok. 760 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
2020-01-14T23:40:05.6517530Z 
2020-01-14T23:40:05.6536506Z      Running build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/env-7957f5bcc786f504
2020-01-14T23:40:05.6571739Z 
---
2020-01-14T23:40:06.6980762Z 
2020-01-14T23:40:06.6981006Z running 1016 tests
2020-01-14T23:40:25.7094345Z i................................................................................................... 100/1016
2020-01-14T23:40:36.0609234Z .................................................................................................... 200/1016
2020-01-14T23:40:43.1829320Z ..................iii......i......i...i......i...................................................... 300/1016
2020-01-14T23:40:48.3248992Z .................................................................................................... 400/1016
2020-01-14T23:40:55.7722826Z ..........................................i..i............................FFFF..................ii.. 500/1016
2020-01-14T23:41:08.8828985Z .................................................................................................... 700/1016
2020-01-14T23:41:08.8828985Z .................................................................................................... 700/1016
2020-01-14T23:41:16.2565937Z ..........................................iiii...................................................... 800/1016
2020-01-14T23:41:30.9619092Z .................................................................................................... 900/1016
2020-01-14T23:41:37.9957643Z ................................................................iiii................................ 1000/1016
2020-01-14T23:41:38.7239351Z failures:
2020-01-14T23:41:38.7245930Z 
2020-01-14T23:41:38.7246798Z ---- lazy.rs - lazy (line 137) stdout ----
2020-01-14T23:41:38.7246882Z error: unused macro definition
2020-01-14T23:41:38.7246882Z error: unused macro definition
2020-01-14T23:41:38.7247096Z  --> lazy.rs:138:1
2020-01-14T23:41:38.7247143Z   |
2020-01-14T23:41:38.7247204Z 4 | / macro_rules! regex {
2020-01-14T23:41:38.7247250Z 5 | |     ($re:literal $(,)?) => {{
2020-01-14T23:41:38.7247319Z 6 | |         static RE: std::lazy::Once<regex::Regex> = std::lazy::Once::new();
2020-01-14T23:41:38.7247374Z 7 | |         RE.get_or_init(|| regex::Regex::new($re).unwrap())
2020-01-14T23:41:38.7247593Z 9 | | }
2020-01-14T23:41:38.7247634Z   | |_^
2020-01-14T23:41:38.7247690Z   |
2020-01-14T23:41:38.7247732Z note: lint level defined here
---
2020-01-14T23:41:38.7248704Z ---- lazy.rs - lazy (line 17) stdout ----
2020-01-14T23:41:38.7248753Z error: unused import: `io`
2020-01-14T23:41:38.7248941Z  --> lazy.rs:20:16
2020-01-14T23:41:38.7249002Z   |
2020-01-14T23:41:38.7249053Z 5 | use std::{env, io};
2020-01-14T23:41:38.7249136Z   |
2020-01-14T23:41:38.7249198Z note: lint level defined here
2020-01-14T23:41:38.7249394Z  --> lazy.rs:16:9
2020-01-14T23:41:38.7249439Z   |
---
2020-01-14T23:41:39.2651941Z   local time: Tue Jan 14 23:41:38 UTC 2020
2020-01-14T23:41:39.3013479Z   network time: Tue, 14 Jan 2020 23:41:39 GMT
2020-01-14T23:41:39.3015035Z == end clock drift check ==
2020-01-14T23:41:39.7967025Z 
2020-01-14T23:41:39.8065922Z ##[error]Bash exited with code '1'.
2020-01-14T23:41:39.8106508Z ##[section]Starting: Checkout
2020-01-14T23:41:39.8108280Z ==============================================================================
2020-01-14T23:41:39.8108349Z Task         : Get sources
2020-01-14T23:41:39.8108391Z Description  : Get sources from a repository. Supports Git, TfsVC, and SVN repositories.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@@ -18,15 +18,16 @@
//! [`RwLock`](../../std/sync/struct.RwLock.html) or
//! [`atomic`](../../core/sync/atomic/index.html) types.
//!
//! Values of the `Cell<T>` and `RefCell<T>` types may be mutated through shared references (i.e.
//! Values of the cell types may be mutated through shared references (i.e.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should just revert these now

@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 17, 2020

Ok, I've still got the tests to pull in, but also noticed we have a little Lazy living in std::io, that's used for static streams. It would be nice to be able to replace it with SyncLazy.

@pitdicker
Copy link
Contributor

Ok, I've still got the tests to pull in, but also noticed we have a little Lazy living in std::io, that's used for static streams. It would be nice to be able to replace it with SyncLazy.

That one sets a destructor that is run during at_exit. I played with it in #58768 (although the final code in that PR is unsound). The destructor brings complications, because child threads might hold a reference to Std* for a brief moment while the main thread terminates. Maybe best to not touch it in this PR.

@pitdicker
Copy link
Contributor

pitdicker commented Jan 17, 2020

Thought about io::Lazy a bit more. Unmerged comment from that PR:

If there are still child threads around when the main thread exits, they get terminated. But there is a small window where they are not yet terminated and may hold a reference to the the data. We therefore store the data in an Arc<T>, keep one of the Arc's in the static, and hand out clones. When the Arc in the static gets dropped by the at_exit handler, the contents will only be dropped if there where no child threads holding a reference.

io::Lazy has to hand out Arcs instead of references. Also initializing it is unsafe, because the destructor must 'behave' itself.

I was wondering if OnceCell can be extended to provide the necessary functionality, but it just requires a very different API that returns smart pointers.

src/libcore/lazy.rs Outdated Show resolved Hide resolved
Ok(unsafe { self.get_unchecked() })
}

/// Consumes the `Once`, returning the wrapped value. Returns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation and some comments do not match the type names. Something to check when the bikeshed is concluded...

src/libstd/lazy.rs Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Jan 20, 2020

☔ The latest upstream changes (presumably #68066) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 20, 2020
@KodrAus
Copy link
Contributor Author

KodrAus commented Jan 21, 2020

@pitdicker pointed out in the RFC that we could reduce the size of the SyncLazy by using a union to store either the initialization function, or the initialization result.

@bors
Copy link
Contributor

bors commented Feb 3, 2020

☔ The latest upstream changes (presumably #68803) made this pull request unmergeable. Please resolve the merge conflicts.

@Dylan-DPC-zz
Copy link

@KodrAus any updates?

@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 23, 2020
@joelpalmer joelpalmer added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 2, 2020
@Dylan-DPC-zz
Copy link

closing this due to inactivity

@Dylan-DPC-zz Dylan-DPC-zz added S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 2, 2020
@KodrAus KodrAus mentioned this pull request Jul 18, 2020
9 tasks
Manishearth added a commit to Manishearth/rust that referenced this pull request Jul 18, 2020
…crum

 Add lazy initialization primitives to std

Follow-up to rust-lang#68198

Current RFC: rust-lang/rfcs#2788

Rebased and fixed up a few of the dangling comments. Some notes carried over from the previous PR:

- [ ] Naming. I'm ok to just roll with the `Sync` prefix like `SyncLazy` for now, but [have a personal preference for `Atomic`](rust-lang/rfcs#2788 (comment)) like `AtomicLazy`.
- [x] [Poisoning](rust-lang/rfcs#2788 (comment)). It seems like there's [some regret around poisoning in other `std::sync` types that we might want to just avoid upfront for `std::lazy`, especially if that would align with a future `std::mutex` that doesn't poison](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/parking_lot.3A.3AMutex.20in.20std/near/190331199). Personally, if we're adding these types to `std::lazy` instead of `std::sync`, I'd be on-board with not worrying about poisoning in `std::lazy`, and potentially deprecating `std::sync::Once` and `lazy_static` in favour of `std::lazy` down the track if it's possible, rather than attempting to replicate their behavior. cc @Amanieu @sfackler.
- [ ] [Consider making`SyncOnceCell::get` blocking](matklad/once_cell#92). There doesn't seem to be consensus in the linked PR on whether or not that's strictly better than the non-blocking variant.

In general, none of these seem to be really blocking an initial unstable merge, so we could possibly kick off a FCP if y'all are happy?

cc @matklad @pitdicker have I missed anything, or were there any other considerations that have come up since we last looked at this?
Manishearth added a commit to Manishearth/rust that referenced this pull request Jul 18, 2020
…crum

 Add lazy initialization primitives to std

Follow-up to rust-lang#68198

Current RFC: rust-lang/rfcs#2788

Rebased and fixed up a few of the dangling comments. Some notes carried over from the previous PR:

- [ ] Naming. I'm ok to just roll with the `Sync` prefix like `SyncLazy` for now, but [have a personal preference for `Atomic`](rust-lang/rfcs#2788 (comment)) like `AtomicLazy`.
- [x] [Poisoning](rust-lang/rfcs#2788 (comment)). It seems like there's [some regret around poisoning in other `std::sync` types that we might want to just avoid upfront for `std::lazy`, especially if that would align with a future `std::mutex` that doesn't poison](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/parking_lot.3A.3AMutex.20in.20std/near/190331199). Personally, if we're adding these types to `std::lazy` instead of `std::sync`, I'd be on-board with not worrying about poisoning in `std::lazy`, and potentially deprecating `std::sync::Once` and `lazy_static` in favour of `std::lazy` down the track if it's possible, rather than attempting to replicate their behavior. cc @Amanieu @sfackler.
- [ ] [Consider making`SyncOnceCell::get` blocking](matklad/once_cell#92). There doesn't seem to be consensus in the linked PR on whether or not that's strictly better than the non-blocking variant.

In general, none of these seem to be really blocking an initial unstable merge, so we could possibly kick off a FCP if y'all are happy?

cc @matklad @pitdicker have I missed anything, or were there any other considerations that have come up since we last looked at this?
Manishearth added a commit to Manishearth/rust that referenced this pull request Jul 18, 2020
…crum

 Add lazy initialization primitives to std

Follow-up to rust-lang#68198

Current RFC: rust-lang/rfcs#2788

Rebased and fixed up a few of the dangling comments. Some notes carried over from the previous PR:

- [ ] Naming. I'm ok to just roll with the `Sync` prefix like `SyncLazy` for now, but [have a personal preference for `Atomic`](rust-lang/rfcs#2788 (comment)) like `AtomicLazy`.
- [x] [Poisoning](rust-lang/rfcs#2788 (comment)). It seems like there's [some regret around poisoning in other `std::sync` types that we might want to just avoid upfront for `std::lazy`, especially if that would align with a future `std::mutex` that doesn't poison](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/parking_lot.3A.3AMutex.20in.20std/near/190331199). Personally, if we're adding these types to `std::lazy` instead of `std::sync`, I'd be on-board with not worrying about poisoning in `std::lazy`, and potentially deprecating `std::sync::Once` and `lazy_static` in favour of `std::lazy` down the track if it's possible, rather than attempting to replicate their behavior. cc @Amanieu @sfackler.
- [ ] [Consider making`SyncOnceCell::get` blocking](matklad/once_cell#92). There doesn't seem to be consensus in the linked PR on whether or not that's strictly better than the non-blocking variant.

In general, none of these seem to be really blocking an initial unstable merge, so we could possibly kick off a FCP if y'all are happy?

cc @matklad @pitdicker have I missed anything, or were there any other considerations that have come up since we last looked at this?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants