-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: