Skip to content
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

Add Vec::resize_default. #41771

Merged
merged 1 commit into from
May 16, 2017
Merged

Add Vec::resize_default. #41771

merged 1 commit into from
May 16, 2017

Conversation

clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey commented May 5, 2017

As suggested by #41758.

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

///
/// If `new_len` is greater than `len()`, the `Vec` is extended by the
/// difference, with each additional slot filled with `Default::default()`.
/// If `new_len` is less than `len()`, the `Vec` is simply truncated.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a note "See also Vec::resize, which uses clone."? I don't know what policy is on that, though (cc @rust-lang/docs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix the docs later today

Copy link
Member

@frewsxcv frewsxcv May 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linking to our methods is good, we do that in other places. What does 'cloning' have to do with this method? Seems like it should say something along the lines of: "If you'd like to specify your own value if the Vec is extended, use Vec::resize".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the docs to reference both methods in each other.

/// assert_eq!(vec, [1, 2]);
/// ```
#[unstable(feature = "vec_resize_default", issue = "41758")]
pub fn resize_default(&mut self, new_len: usize, value: T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

surely it's not supposed to take a value argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is what I get for making a PR right before running to catch the bus

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I fixed this btw)

@@ -1301,6 +1301,41 @@ impl<T: Clone> Vec<T> {
}
}

impl<T: Default> Vec<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought, separate impl blocks for different bounds seems archaic (from the time before where clauses), so we probably don't want to continue that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I agree, although for now I think it'd be best to continue the pattern and refactor the entire file in a future PR.

Also, this seems like a good candidate for a fmt RFC.

@Mark-Simulacrum Mark-Simulacrum added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 7, 2017
@@ -1301,6 +1306,47 @@ impl<T: Clone> Vec<T> {
}
}

impl<T: Default> Vec<T> {
/// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we (the docs team) for the time being, don't add () to the end of method names in documentation, so this len() should be len, ideally linking to the associated method. alternatively, you could just say "...so that its length is equal to new_len." not a big deal though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will modify on both methods! This was copy-pasted from the old docs.

@carols10cents
Copy link
Member

Looks like there's a test failure:

[01:03:01] failures:
[01:03:01] 
[01:03:01] ---- vec.rs - vec::Vec<T>::resize_default (line 1321) stdout ----
[01:03:01] 	error: use of unstable library feature 'vec_resize_default' (see issue #41758)
[01:03:01]  --> <anon>:5:5
[01:03:01]   |
[01:03:01] 5 | vec.resize_default(5);
[01:03:01]   |     ^^^^^^^^^^^^^^
[01:03:01]   |
[01:03:01]   = help: add #![feature(vec_resize_default)] to the crate attributes to enable
[01:03:01] 
[01:03:01] error: use of unstable library feature 'vec_resize_default' (see issue #41758)
[01:03:01]  --> <anon>:9:5
[01:03:01]   |
[01:03:01] 9 | vec.resize_default(2);
[01:03:01]   |     ^^^^^^^^^^^^^^
[01:03:01]   |
[01:03:01]   = help: add #![feature(vec_resize_default)] to the crate attributes to enable
[01:03:01] 
[01:03:01] error: aborting due to previous error(s)
[01:03:01] 
[01:03:01] thread 'rustc' panicked at 'Box<Any>', /checkout/src/librustc/session/mod.rs:216
[01:03:01] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:03:01] 
[01:03:01] 
[01:03:01] failures:
[01:03:01]     vec.rs - vec::Vec<T>::resize_default (line 1321)
[01:03:01] 
[01:03:01] test result: FAILED. 404 passed; 1 failed; 4 ignored; 0 measured
[01:03:01] 
[01:03:01] error: test failed, to rerun pass '--doc'
[01:03:01] 

@carols10cents carols10cents added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 8, 2017
///
/// [`resize`]: #method.resize
#[unstable(feature = "vec_resize_default", issue = "41758")]
pub fn resize_default(&mut self, new_len: usize) {
Copy link
Contributor

@nikomatsakis nikomatsakis May 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, should we just implement this with self.resize(new_len, T::default())? I guess it would invoke default even when you don't need it...but it seems odd for this implementation to stray from the other resize (e.g., that version calls self.extend_with_element(), maybe we should do the same?).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that, but I decided we couldn't since that would require T: Clone, right? Same for calling self.extend_with_element(). Ideally we'd have some trait that is "produce more of the same value" which would be be implemented for both T: Default and T: Clone. Unless we have an impl impl Clone for T where T: Default, which could work (i.e., calling Default::default each time, but might be impossible to add today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I was mentioning about a more efficient implementation is that we could specialise this to just call extend_with_element for Clone + Default.

I can add this before merge if it's desired for the initial PR, although I might not be free this week to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also potentially add a clippy lint that warns if a type implements Default but not Clone, but IDK if that's too niche.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, that's true, I forgot that Default doesn't imply Clone.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, ok, I give up =) I was going to suggest maybe combining extend_with_{element,default} into one thing that takes a closure, but that seems to require an extra clone. Seems ok as is I suppose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try and figure something out; I have a feeling that I know what to do.

@alexcrichton alexcrichton added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label May 9, 2017
@Mark-Simulacrum
Copy link
Member

A few warnings to remove, and then probably ready for re-review.

[00:01:40] error: unused variable: `count`
[00:01:40]     --> /checkout/src/libcollections/vec.rs:1337:17
[00:01:40]      |
[00:01:40] 1337 |             let count = new_len - len;
[00:01:40]      |                 ^^^^^
[00:01:40]      |
[00:01:40]      = note: #[deny(unused_variables)] implied by #[deny(warnings)]
[00:01:40] note: lint level defined here
[00:01:40]     --> /checkout/src/libcollections/lib.rs:30:9
[00:01:40]      |
[00:01:40] 30   | #![deny(warnings)]
[00:01:40]      |         ^^^^^^^^
[00:01:40] 
[00:01:40] error: aborting due to previous error

@clarfonthey
Copy link
Contributor Author

So, I hopefully fixed the errors and also generalised extend_with_element and extend_with_default with a trait that's admittedly kind of ugly, but small enough and gets the job done.

@Mark-Simulacrum
Copy link
Member

Travis is failing. @clarcharr Just to check, are you able to build locally? Is there something we can help resolve to assist with that? (It's fine if you use travis for tests, just want to make sure that there's nothing on our side blocking your ability to build locally).

[00:01:38] error[E0277]: the trait bound `T: core::clone::Clone` is not satisfied
[00:01:38]     --> /checkout/src/libcollections/vec.rs:1324:9
[00:01:38]      |
[00:01:38] 1324 | impl<T> ExtendWith<T> for ExtendElement<T> {
[00:01:38]      |         ^^^^^^^^^^^^^ the trait `core::clone::Clone` is not implemented for `T`
[00:01:38]      |
[00:01:38]      = help: consider adding a `where T: core::clone::Clone` bound
[00:01:38]      = note: required by `vec::ExtendElement`
[00:01:38] 
[00:01:38] error[E0277]: the trait bound `T: core::clone::Clone` is not satisfied
[00:01:38]     --> /checkout/src/libcollections/vec.rs:1325:5
[00:01:38]      |
[00:01:38] 1325 |     fn next(&self) -> T { self.0.clone() }
[00:01:38]      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `core::clone::Clone` is not implemented for `T`
[00:01:38]      |
[00:01:38]      = help: consider adding a `where T: core::clone::Clone` bound
[00:01:38]      = note: required by `vec::ExtendElement`
[00:01:38] 
[00:01:38] error[E0277]: the trait bound `T: core::clone::Clone` is not satisfied
[00:01:38]     --> /checkout/src/libcollections/vec.rs:1326:5
[00:01:38]      |
[00:01:38] 1326 |     fn last(self) -> T { self.0 }
[00:01:38]      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `core::clone::Clone` is not implemented for `T`
[00:01:38]      |
[00:01:38]      = help: consider adding a `where T: core::clone::Clone` bound
[00:01:38]      = note: required by `vec::ExtendElement`
[00:01:38] 
[00:01:38] error: aborting due to 3 previous errors

// This code generalises `extend_with_{element,default}`.
trait ExtendWith<T> {
fn next(&self) -> T;
fn last(self) -> T { self.next() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Given that this is a private trait with two impls, I'd say remove the default impl and just move this method to the ExtendDefault trait.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is clever.

/// difference, with each additional slot filled with `value`.
/// If `new_len` is less than `len()`, the `Vec` is simply truncated.
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since len is a method, not a variable, I think it makes sense for it to be new_len (variable) and len() (method) in the comment, as it was before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is based upon the earlier suggestion by @frewsxcv; the docs team has decided to not put the parentheses on the methods, so, I will go with the convention says.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I was unaware. Sorry for the noise.

Copy link
Contributor Author

@clarfonthey clarfonthey May 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, I filed Manishearth/rust-clippy#1750 so that we can maybe lint for this convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I find that new convention pretty confusing! I agree that this PR ought to follow it, but I think we ought to consider changing it.

@clarfonthey
Copy link
Contributor Author

@Mark-Simulacrum There isn't actually anything preventing me from testing locally, other than the fact that I need to remember to set my computer down for an hour and build once so that I can actually test quickly. I've been moving around a lot the past few days and haven't had time. :P

@clarfonthey
Copy link
Contributor Author

Note: tests pass now. Is there anything left to do before merge? @nikomatsakis

@frewsxcv frewsxcv added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels May 13, 2017
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented May 15, 2017

📌 Commit c2c0641 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented May 15, 2017

⌛ Testing commit c2c0641 with merge b89bcf5...

@bors
Copy link
Contributor

bors commented May 15, 2017

💔 Test failed - status-appveyor

@alexcrichton
Copy link
Member

frewsxcv added a commit to frewsxcv/rust that referenced this pull request May 16, 2017
@bors
Copy link
Contributor

bors commented May 16, 2017

⌛ Testing commit c2c0641 with merge 4d09a0e...

bors added a commit that referenced this pull request May 16, 2017
Add Vec::resize_default.

As suggested by #41758.
@bors
Copy link
Contributor

bors commented May 16, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 4d09a0e to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants