-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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 Option::get_or_insert_default
#82901
Comments
It's not obvious to me at all from the name that this modifies the |
Hmm I hadn't considered that. |
…=joshtriplett Add Option::get_or_default Tracking issue: rust-lang#82901 The original issue is rust-lang#55042, which was closed, but for an invalid reason (see discussion there). Opening this to reconsider (I hope that's okay). It seems like the only gap for `Option` being "entry-like". I ran into a need for this method where I had a `Vec<Option<MyData>>` and wanted to do `vec[n].get_or_default().my_data_method()`. Using an `Option` as an inner component of a data structure is probably where the need for this will normally arise.
…=joshtriplett Add Option::get_or_default Tracking issue: rust-lang#82901 The original issue is rust-lang#55042, which was closed, but for an invalid reason (see discussion there). Opening this to reconsider (I hope that's okay). It seems like the only gap for `Option` being "entry-like". I ran into a need for this method where I had a `Vec<Option<MyData>>` and wanted to do `vec[n].get_or_default().my_data_method()`. Using an `Option` as an inner component of a data structure is probably where the need for this will normally arise.
…=joshtriplett Add Option::get_or_default Tracking issue: rust-lang#82901 The original issue is rust-lang#55042, which was closed, but for an invalid reason (see discussion there). Opening this to reconsider (I hope that's okay). It seems like the only gap for `Option` being "entry-like". I ran into a need for this method where I had a `Vec<Option<MyData>>` and wanted to do `vec[n].get_or_default().my_data_method()`. Using an `Option` as an inner component of a data structure is probably where the need for this will normally arise.
Option::get_or_default
Option::get_or_insert_default
…ou-se Rename `Option::get_or_default` to `get_or_insert_default` ...as [suggested](rust-lang#82901 (comment)) by `@m-ou-se.` In hindsight this seems rather obvious, at least to me. r? `@joshtriplett`
+1 on the name I wanted to use this today, but it's still experimental. 😆 |
+1 -- was looking for this exact method today |
@rustbot ping libs Let's see if this works now? Would be nice to have this FCP'ed. |
LGTM @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
@rfcbot concern is this in the same category as resize_default Many years ago we deleted
It seems like it came down to just not being worth dedicating a whole new method given how rarely I suppose |
My own experience (which may or may not be representative) tells that in every single case I wanted |
Be aware that whether or not you want the default value is not the only consideration here. You also require a situation in which use std::collections::BTreeSet;
use std::iter;
fn main() {
let mut junks = None;
for (id, value) in iter::repeat(("junk", 99)).take(10) {
if id == "junk" {
junks.get_or_insert_with(BTreeSet::default).insert(value);
}
}
println!("{:?}", junks);
} With get_or_insert_default: error[E0282]: type annotations needed for `Option<T>`
--> src/main.rs:5:9
|
5 | let mut junks = None;
| ^^^^^^^^^
...
8 | junks.get_or_insert_default().insert(value);
| ------ type must be known at this point |
Very good example. However, in my opinion it doesn't lower the value of |
Is there anything blocking stabilisation of this? |
What is the current status? Can we stabilize it? |
Are there steps to move this forward and stabilize? I just encountered tons of these cases in PGRX - and was surprised it wasn't stable yet |
My opinion remains #82901 (comment) and I would prefer not to grow the API of I am open to being overruled 4:1 if I'm wrong about this. Among the unchecked boxes in the FCP proposal, Jane has departed the team since then but I am interested to hear @BurntSushi's opinion (and if the other team members could reaffirm that they still like this method, since those approvals all happened before the critical comments — as did mine before I eventually changed my mind). |
I think for me, With that said, if most uses of this new routine require inference help, then I would agree that the juice does not seem worth squeeze. @nyurik in particular linked to a code sample where the I would say my current opinion is "weakly in favor if inference failures don't happen in most cases." But if using this method just means that you'll likely need to write down the type anyway, then I think my position would be "not strongly opposed." |
In the compiler, there are 28 calls of Option::get_or_insert_with and Option::get_or_insert_default currently. 79% need to stick with get_or_insert_with because they are inserting with something that is not the default value. (This is quite divergent from #82901 (comment). But it closely matches the ratio of unwrap_or_else to unwrap_or_default in the compiler: 83% of those calls are unwrap_or_else.) Of the remainder, the 2 in compiler/rustc_session/src/options.rs and the 3 in compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs are inserting default into a struct field or function argument, where the type already needs to have been declared anyway. And 1 in compiler/rustc_mir_transform/src/elaborate_box_derefs.rs uses get_or_insert_default but requires inference help. if let VarDebugInfoContents::Place(place) = &mut debug_info.value {
- let mut new_projections = None;
+ let mut new_projections: Option<Vec<_>> = None;
let mut last_deref = 0;
for (i, (base, elem)) in place.iter_projections().enumerate() {
let base_ty = base.ty(&body.local_decls, tcx).ty;
if elem == PlaceElem::Deref && base_ty.is_box() {
- let new_projections = new_projections.get_or_insert_with(Vec::new);
+ let new_projections = new_projections.get_or_insert_default();
let (unique_ty, nonnull_ty, ptr_ty) =
build_ptr_tys(tcx, base_ty.boxed_ty(), unique_did, nonnull_did); |
In PGRX which was linked above as a motivating use case, there are 3 functions that call Option::get_or_insert_with using a default, of which 2 (here and here) would require adding a type to the declaration of the Option local variable in order to be able to use get_or_insert_default with it, while 1 (here) would not. |
My personal take on that scenario is that adding a type annotation to the variable is a readability win. I prefer to know/define the types of things upfront for clarity, and then value-modifying code is not responsible for providing type information to the reader or to the compiler. |
I just did a quick github search for |
I am not sure I will personally end up using @rfcbot resolve is this in the same category as resize_default |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
Rollup merge of rust-lang#129087 - slanterns:option_get_or_insert_default, r=dtolnay Stabilize `option_get_or_insert_default` Closes: rust-lang#82901. `@rustbot` label: +T-libs-api r? libs-api
Feature gate:
#![feature(option_get_or_insert_default)]
This is a tracking issue for adding
Option::get_or_insert_default
.Basically, it is a shorthand for
option.get_or_insert_with(Default::default)
. It differs withunwrap_or_default
since it does not consume theOption
. This is useful, for example, when you have anOption
as a struct field or inside a data structure likeVec<Option<T>>
.Public API
Steps / History
get_or_default
#55042get_or_default
toget_or_insert_default
: RenameOption::get_or_default
toget_or_insert_default
#82977Unresolved Questions
The text was updated successfully, but these errors were encountered: