-
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 Vec::resize_with and resize_default #41758
Comments
This would be an interesting addition for types which support In the future, just FYI, feature requests should go in the RFCs repository. |
Ah OK, noted. That's even for feature requests like this one that don't deserve an RFC? |
Yep! The general rule is either PR here or RFC elsewhere. Also, @joshlf would you mind renaming this issue to "Tracking issue for Vec::resize_default" ? And @nikomatsakis would you mind tagging it? |
Gotcha; thanks! |
…sakis Add Vec::resize_default. As suggested by rust-lang#41758.
Add Vec::resize_default. As suggested by #41758.
@rust-lang/libs Nominating for stabilization. The only potential concern is that we can generalize this to take a closure (see below). I don't know that it'd be all that useful, though, so I'm inclined to say that we shouldn't do so, and fn resize_with(&mut self, new_len: usize, f: F)
where F: FnMut() -> T |
@Mark-Simulacrum I'd be willing to make a PR that adds |
I might lean more towards just having |
My concern is that |
Discoverability is pretty easily fixed by just having some documentation, though, right? I like the power of |
You'd just use |
The @rust-lang/libs team discussed this today and feel like |
I've submitted #49559 implementing |
Introduce Vec::resize_with method (see rust-lang#41758) In rust-lang#41758, the libs team decided they preferred `Vec::resize_with` over `Vec::resize_default()`. Here is an implementation to get this moving forward. I don't know what the removal process for `Vec::resize_default()` should be, so I've left it in place for now. Would be happy to follow up with its removal.
Isn't |
@Kerollmops And |
So, if we deprecate the |
…r=SimonSapin Deprecate the unstable Vec::resize_default As a way to either get additional feedback to stabilize or help move nightly users off it. Tracking issue: rust-lang#41758 (comment) r? @SimonSapin
…r=SimonSapin Deprecate the unstable Vec::resize_default As a way to either get additional feedback to stabilize or help move nightly users off it. Tracking issue: rust-lang#41758 (comment) r? @SimonSapin
…r=SimonSapin Deprecate the unstable Vec::resize_default As a way to either get additional feedback to stabilize or help move nightly users off it. Tracking issue: rust-lang#41758 (comment) r? @SimonSapin
If the matter is open to discussion: I find that writing |
Is there any reason not to stabilize this right now? Offering functions that do the same thing as another function but with fewer arguments is a very common thing, and it's zero-cost in Rust. |
I'd like to have resize_default. I'm about to use it in one of my projects, plus I think it's good to have pairity with the other or_default methods, like EDIT: I forgot one of my favorites, |
I like resize_default, it's very clear and more newbie friendly. |
I disagree! Edit: When I say "leaving it in", I actually thought it was already stable (haven't compiled code yet). I discovered it through rust-analyzer's autocomplete, thought "resize_default? Yes that's exactly what I want". Some empirical evidence for @joshlf's discoverability argument. No way would autocomplete have suggested |
From a quick search on grep.app (https://grep.app/search?q=.resize_with&filter[lang][0]=Rust), I decided to categorize every line using Default parameter usagesdata_buffer.resize_with(batch_size, T::T::default);
buf.resize_with(batch_size, || 0);
buf.resize_with(batch_size, || 0);
self.characters.resize_with(cell_count, || None);
self.buffer.resize_with(len, Default::default);
self.buffer.resize_with(len, Default::default);
self.buffer.resize_with(len, Default::default);
data.resize_with(len, || None);
this.resize_with(i + 1, || None);
table_entries.resize_with(msix_vectors as usize, Default::default);
pba_entries.resize_with(num_pba_entries, Default::default);
items.resize_with(capacity, Default::default);
empty_items.resize_with(self.items.len(), Vec::default);
handles.resize_with(widgets.len().saturating_sub(1), || DragHandle::new());
.resize_with(self.widgets.len().saturating_sub(1), || DragHandle::new());
detected.resize_with(DETECTED_SLOTS_NUM, || Mutex::new(HashSet::default()));
buffer.resize_with(width * height, Default::default);
palette.resize_with(palette_length * 3, Default::default);
buffer.resize_with(width * 3, Default::default);
self.v.resize_with((idx + 1).max(self.v.len()), || None);
v.resize_with(255, Default::default);
instances.resize_with(max_instances, || Mutex::new(None));
data.resize_with(size, T::default);
vals.resize_with(BUCKETS, Default::default);
.resize_with(fluid.num_particles(), || RwLock::new(Vec::new()))
.resize_with(fluid.num_particles(), || RwLock::new(Vec::new()))
.resize_with(boundary.num_particles(), || RwLock::new(Vec::new()))
pixels_resolved_this_stage.resize_with(n_workers, || Mutex::new(Vec::new()));
rtrees.resize_with((grid_width * grid_height) as usize, || RwLock::new(RTree::new());
handles.resize_with(INSTANCES_PER_RUN, || None);
self.cur_buffer.resize_with(cols * rows, Default::default);
.resize_with(self.cur_buffer.len(), Char::default);
self.0.resize_with(id, Default::default);
target_candidates.resize_with(test.targets(), Default::default);
res.resize_with(n, Point::identity);
vec.resize_with(Self::capacity(), Default::default);
v.resize_with(rounded_size, T::default);
.resize_with((self.width * self.height) as usize, GridStoreCell::default);
.resize_with((self.width * self.height) as usize, GridStoreCell::default);
self.0.resize_with(i + 1, Default::default);
buckets.resize_with(num_buckets, Default::default);
buckets.resize_with(num_buckets, Default::default);
texels.resize_with((w * h) as usize * pf.canals_len(), Default::default);
self.traces.resize_with(TRACE_SIZE, Trace::default);
hotplug_slots.resize_with(HOTPLUG_COUNT, HotPlugState::default);
d.resize_with(pair.0, Default::default);
vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default);
plaintext_buf.resize_with(ci.len(), u8::default);
notoken_packet.resize_with(1200, u8::default);
self.children.resize_with(elements_count, || Vec::new());
envs_with_walked_drivers.resize_with(expected_len, Assoc::new);
entries.resize_with(rows * cols, Default::default);
v.resize_with(size, Default::default);
vals.resize_with(BUCKETS, Default::default);
pixels.resize_with(capacity, Default::default);
enc.resize_with(enc.len() + octects_needed, Default::default);
inputs.resize_with(edge.to.1 + 1, || None);
ids.resize_with(maxlen, || None);
.resize_with(meta_count.0, Default::default);
self.lines.resize_with(rows.len(), Default::default);
out.resize_with(self.h.len(), || None::<Tensor>);
kvm.vec_events.resize_with(new_len, || None);
output.resize_with(output.capacity(), Default::default);
self.obj_vec.resize_with(self.num_world_tiles + 1, || None);
buf.resize_with(512, Default::default);
buf.resize_with(512, Default::default);
blob.resize_with(size as usize, Default::default);
self.threads.resize_with(tid + 1, Default::default);
enc_id_vec.resize_with(32, Default::default);
new_reserved.resize_with(new_len, || AtomicU32::new(0));
.resize_with(meta_count.0, Default::default);
self.children.resize_with(ENTRIES_PER_NODE, || None);
new_data.resize_with(row * new_stride, Default::default);
new_data.resize_with(row * new_stride, Default::default);
self.ifd_list.resize_with(ifd_num + 1, Default::default);
self.data.resize_with(new_size, Default::default);
col_mat.resize_with(sparse_len, || Arc::new(Mutex::new(vec![])));
prod.resize_with(lhs + 1, || Vec::new());
c::WSAEFAULT => buffer.resize_with(1 + (len as usize) / mem::size_of::<usize>(), Default::default),
chart.resize_with(toks.len() + 1, std::default::Default::default);
vals.resize_with(BUCKETS, Default::default);
in_out.resize_with(ct_len + AUTH_TAG_BYTES, || 0);
buf.resize_with(test_str.as_bytes().len(), Default::default);
quant_new_rec.resize_with(new_height, Default::default);
msgs.resize_with(n * MSG_SIZE, Default::default); Non-default parameterself.dirty.resize_with(cell_count, || true);
.resize_with((self.width * self.height) as usize, || value);
authorities.resize_with(30, || PeerId::random());
full_nodes.resize_with(30, || PeerId::random());
self.element_yoga_nodes.resize_with(elements_count, || unsafe { YGNodeNew() });
self.text_yoga_nodes.resize_with(texts_count, || unsafe { YGNodeNew() });
shards.resize_with(N_SHARDS, || (AccessQueue::default(), FastLock::new(Shard::new(shard_capacity))));
positions.resize_with(positions.len() + sub_niddle.len(), || { pos += 1; pos - 1 });
isf_data.passes.resize_with(isf.passes.len(), || ...); // https://github.com/nannou-org/nannou/blob/master/nannou_isf/src/pipeline.rs#L948-L958
self.tabs.resize_with(num_cols.0, || { let is_tabstop = index % INITIAL_TABSTOPS == 0; index += 1; is_tabstop });
self.inner.resize_with(new_len, f);
self.pointers.resize_with(stack + 1, || Pointer { start: last_end, end: last_end });
self.layouts.resize_with(texts_count, || TextLayoutState { font_size: 16., line_height: 20., single_line_width: 0., glyph_ids: Vec::new(), xs: Vec::new(), break_hints: Vec::new(), breaks: Vec::new() }});
new_args.resize_with(arg_count, || FlatArg::Default);
texts.resize_with(texts_count, || unsafe { (gpu.create_buffer(), 0, 0.) })
.resize_with(expected_len, || Subtype::underspecified(n("ddd_bit")).0);
*mgr += self.list.inner_mut().resize_with(len, |n| ListEntry::new(n, n == active));
self.pending_pushes.resize_with(WORK_GROUP_WIDTH as usize, || GpuPush { dir_id: [-1.0; 4] });
data.resize_with(length + 1, || rng.gen());
bufs.resize_with(capacity, || Mutex::new(Buf { status: BufStatus::Unused, data: vec![0; 1 << T::BLOCK_SIZE_LOG2 as usize] }));
data.resize_with(capacity + 1, MaybeUninit::uninit);
self.nodes.resize_with(1, || g.gen_leaf(0));
val.resize_with(x, || self.clone());
self.pending.resize_with(offset + 1, || Output { buffer: writer.buffer(), done: false });
alloc.resize_with(alloc_cell_w, || { let mut out = Vec::with_capacity(alloc_cell_w); out.resize(alloc_cell_w, None); out })
bnodes.resize_with(*id, BlankNode::default)
enc_id_vec.resize_with(32, Default::default);
self.data.resize_with(size, || 0);
v.resize_with(opt.k, || unreachable!());
v.resize_with(opt.k, || unreachable!()); No default implementation, but one could be derivedv.resize_with(nports as usize, || PortState::new());
self.entries.resize_with(capacity, || CacheEntry { items: Vec::new(), occupied: false });
fluid_fluid_contacts.resize_with(fluids.len(), || ParticlesContacts::new());
fluid_boundary_contacts.resize_with(fluids.len(), || ParticlesContacts::new());
boundary_boundary_contacts.resize_with(boundaries.len(), || ParticlesContacts::new());
v.resize_with(hub_desc.num_ports as usize, || super::PortState::new());
out.resize_with(r#in.len(), || MaybeUninit::<wasi::Event>::zeroed().assume_init());
out.resize_with(in_.len(), || { MaybeUninit::<wasi_unstable::Event>::zeroed().assume_init() }) UBThere was one usage from config_ids.resize_with(num_configs as usize, || std::mem::zeroed()); |
Thanks for the info @xfix. If the majority of calls can use |
For completeness I've scanned crates.io for uses of At a glance the results seem to align with the ones posted above - roughly half of the invocations just use the default value. On the other hand, there are just 207 uses of |
For reference, |
for reference, how many unwrap_or with the default value for the type ( |
Here are all occurrences of My point is, since the use of |
I think the point is that there are several other I'm pretty sure |
|
@zakarumych That's currently done for |
@scottmcm In generic environment, with 'Vec<T>' where 'T: Default', you can use either '.resize_default()' or '.resize_with(Default::default())', the former can be specialized for integers and later not. |
|
Currently,
Vec
has aresize
method which takes anew
parameter so that if the resize involves growing the vector, thenew
parameter is cloned into each newly-created cell in the vector.T
must implementClone
in order for this method to be available.It would be useful to add a
resize_default
method that instead requires thatT: Default
, and callsT::default()
to fill the newly-created cells. Not only would this be ergonomic, but for certain implementations ofT::default
, it might allow the compiler to make better optimizations.The text was updated successfully, but these errors were encountered: