Repository navigation
Tracking Issue for once_cell_try #109737
Copy link
Copy link
Open
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
Description
This supercedes #74465 after a portion of once_cell was stabilized with #105587
Feature gate: #![feature(once_cell_try)]
This is a tracking issue for the *try* methods that go with the once_cell feature. Initially they were part of stabilization under once_cell (#105587) but was removed due to compatibility concerns with try trait v2 (#105587 (comment)).
Public API
impl<T> OnceCell<T> {
pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>;
}
impl<T> OnceLock<T> {
pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result<T, E>;
}Steps / History
- Original implementation: Add lazy initialization primitives to std #72414
- Try trait changes: Use
Trytrait to makeOnce[Cell | Lock]::get_or_try_initgeneric over return type #107122 - Final comment period (FCP)1
- Stabilization PR
Unresolved Questions
- None yet.
cc @joboet @matklad just for reference
Footnotes
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.This issue / PR is in PFCP or FCP with a disposition to merge it.proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
Activity
BurntSushi commentedon Mar 30, 2023
I think I'd say that the question of whether to make the fallible routines generic over
Tryis unresolved at this point. See: #107122 (comment) and #84277 (comment)tgross35 commentedon Mar 30, 2023
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
rustcBurntSushi commentedon Mar 30, 2023
I posted a comment on that PR with the results of a quick search that I did: #107122 (comment)
sutes-work commentedon Feb 22, 2024
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
poisonmethod on Once isn't exposed publicly. It would be nice of Once had an API that would support this.tgross35 commentedon Feb 22, 2024
@sutes-work can you give an example of what a TryLazyLock API would do differently from
get_or_try_init?sutes-work commentedon Feb 22, 2024
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.
tgross35 commentedon Feb 22, 2024
Is the main goal of the suggestion to save storage space? That is the case already, the actual implementation has
rust/library/std/src/sync/lazy_lock.rs
Lines 80 to 84 in 397937d
See #107329
sutes-work commentedon Feb 22, 2024
Right, but F is
fn() -> Twhen I want F to befn() -> Result<T, E>.tgross35 commentedon Feb 22, 2024
Oh are you just looking for something to make
LazyCell/LazyLockwith result functions more ergonomic?This works as-is:
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.
sutes-work commentedon Feb 23, 2024
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
TryOnceLockwould be relatively simple: it'sOncethat seems hard. One option is to expose thepoisonmethod, but that feels like a hack to me since in this case it's really the same as the Incomplete state (there was no panic).tgross35 commentedon Feb 23, 2024
The usecase in general makes sense, you might be interested to bring it up to the
once_cellcrate, where a lot of this API was initially developed.Having a panicky initializer function sounds like a pretty unfortunate interface. If you really can't use a
ResultAPI instead,call_once_forcemight be what you need. Or use acatch_unwindwrapper around your initializer function to convert those poisons toResults.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/
sutes-work commentedon Feb 23, 2024
I'll have a look into that.
I think there might be a misunderstanding: I'm commenting on the way that
get_or_try_initseems to be implemented: https://doc.rust-lang.org/src/std/sync/once_lock.rs.html#385. It calls poison there, but poison isn't public so I can't implement my own TryLazyLock using Once.For now, I need stable Rust so I've just used the equivalent of:
(You can see it here: https://fxrev.dev/995693.)
briansmith commentedon Jun 5, 2024
The documentation says:
But, it is missing the most important part:
Importantly, even though the internal
OnceinOnceLockmay be poisoned, there is actually no poisoning inOnceLock, asOnceLockwill consider a poisoned internalOnceto be uninitialized.28 remaining items
arch: isolate daemon contract from local lifecycle (#441)
Dev -> Main: sync v0.5.0 development (#479)
docs(roadmap): Phase 10 Task 3 follow-ups + scrub stale comments
fix(decode): propagate FSETableError from predefined cache init + reg…
perf(decode): cache predefined FSE tables (small-4k-log-lines −69%) (#…
fix(type-host): stop caching a materialise_host_script I/O failure fo…
fix(type-host): stop caching a materialise_host_script I/O failure fo…
fix(type-host): stop caching a materialise_host_script I/O failure fo…
fix(type-host): stop caching a materialise_host_script I/O failure fo…
fix: reuse one tokio runtime per block_on client (#140)
fix(build): replace epoxy-rs
fix(build): replace epoxy-rs (#625)
wip(utok): step 1 - fallible RankTable::parse + OnceFallible + BpeLoa…