-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking Issue for once_cell_try
#109737
Comments
I think I'd say that the question of whether to make the fallible routines generic over |
I'm kind of curious of how and how often these functions are used in the ecosystem, does anyone know of any examples? They're not used anywhehre in |
I posted a comment on that PR with the results of a quick search that I did: #107122 (comment) |
Related to this, I want something like: TryLazyLock. Not sure if this is the right place to comment (sorry if it's not!). I looked to see how get_or_try_init is implemented, but unfortunately, the |
@sutes-work can you give an example of what a TryLazyLock API would do differently from |
So I can do this:
and it's not so bad, but it costs me space for the init_fn. I should be able to share that space with T. I should be able to have:
It's a bit rough, but hopefully you get the idea. |
Is the main goal of the suggestion to save storage space? That is the case already, the actual implementation has // We use the state of a Once as discriminant value. Upon creation, the state is
// "incomplete" and `f` contains the initialization closure. In the first call to
// `call_once`, `f` is taken and run. If it succeeds, `value` is set and the state
// is changed to "complete". If it panics, the Once is poisoned, so none of the
// two fields is initialized.
union Data<T, F> {
value: ManuallyDrop<T>,
f: ManuallyDrop<F>,
}
pub struct LazyLock<T, F = fn() -> T> {
once: Once,
data: UnsafeCell<Data<T, F>>,
} rust/library/std/src/sync/lazy_lock.rs Lines 80 to 84 in 397937d
See #107329 |
Right, but F is |
Oh are you just looking for something to make This works as-is: #![feature(lazy_cell)]
use std::sync::LazyLock;
static OK: LazyLock<Result<&'static str, &'static str>> =
LazyLock::new(|| Ok("success!"));
static ERROR: LazyLock<Result<&'static str, &'static str>> =
LazyLock::new(|| Err("error!"));
fn main() -> Result<(), String> {
println!("ok value: {}", (*OK)?);
println!("error value: {}", (*ERROR)?);
Ok(())
} That prints:
There is an ergonomic downside that you can't get an owned error. Feel free to propose an API if you have something in mind, or share code snippets that could be improved. |
That's not what I want. I want to call the callback multiple times so it keeps trying. I want:
As you noted, you don't get an owned error, which is problematic for me since the errors I'm dealing with aren't copyable (which I believe is generally the case). It's possible that such an API isn't generally useful which is why I hinted that exposing an API on Once that allows me to build such a thing myself would be helpful; I think my own |
The usecase in general makes sense, you might be interested to bring it up to the Having a panicky initializer function sounds like a pretty unfortunate interface. If you really can't use a Feel free to drop by on Zulip to discuss this further if you're trying to refine some ideas for new APIs https://rust-lang.zulipchat.com/ |
I'll have a look into that.
I think there might be a misunderstanding: I'm commenting on the way that For now, I need stable Rust so I've just used the equivalent of:
(You can see it here: https://fxrev.dev/995693.) |
The documentation says:
But, it is missing the most important part: - If the cell was empty and f failed, an error is returned.
+ If the cell was empty and f failed, an error is returned, and the cell remains uninitialized. Importantly, even though the internal |
…s possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737
…s possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737
… possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737
… possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737
* Anki: Replace lazy_static with once_cell Unify to once_cell, lazy_static's replacement. The latter in unmaintained. * Anki: Replace once_cell with stabilized LazyCell / LazyLock as far as possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737 * Declare correct MSRV (dae) Some of our deps require newer Rust versions, so this was misleading. Updating the MSRV also allows us to use .inspect() on Option now
If https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.get_or_insert_with |
std::sync::LazyLock and std::sync::OnceLock have stabilized, so replace once_cell::sync::Lazy and once_cell::sync:OnceCell with them when possible. Leave one use of once_cell::sync::OnceCell since we use get_or_try_init which hasn't stabilized yet. rust-lang/rust#109737
This supercedes #74465 after a portion of
once_cell
was stabilized with #105587Feature gate:
#![feature(once_cell_try)]
This is a tracking issue for the
*try*
methods that go with theonce_cell
feature. Initially they were part of stabilization underonce_cell
(#105587) but was removed due to compatibility concerns with try trait v2 (#105587 (comment)).Public API
Steps / History
Try
trait to makeOnce[Cell | Lock]::get_or_try_init
generic over return type #107122Unresolved Questions
cc @joboet @matklad just for reference
Footnotes
https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩
The text was updated successfully, but these errors were encountered: