Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd retain function #59
Conversation
|
I have questions. Also, needs tests. Thanks! |
| } | ||
| } | ||
| Heap { ptr, capacity } => unsafe { | ||
| Vec::from_raw_parts(ptr, len, capacity).retain(f); |
This comment has been minimized.
This comment has been minimized.
emilio
Aug 17, 2017
Member
Wouldn't this drop the vector afterwards, causing a use after free the next time it's accessed? Also, I see nothing updating the ptr field, which may change I suppose.
This comment has been minimized.
This comment has been minimized.
torkleyy
Aug 17, 2017
Yes, it would be dropped afterwards. I think you should get the new pointer, len and capacity from the vec and mem::forget it afterwards.
| if !f(&*array.ptr().offset(i as isize)) { | ||
| del += 1; | ||
| } else if del > 0 { | ||
| swap(&mut array.ptr().offset((i - del) as isize), &mut array.ptr().offset(i as isize)); |
This comment has been minimized.
This comment has been minimized.
|
@emilio I've addressed your comments and added tests, thanks for the help! |
|
Travis only failed on nightly. Probably a regression in nightly. EDIT: woops nevermind, looks like I accidentally broke nostd support. I just added a commit that should fix this. |
| } | ||
| } | ||
| if del > 0 { | ||
| self.len = len - del; |
This comment has been minimized.
This comment has been minimized.
emilio
Aug 18, 2017
Member
nit: This can just be self.len -= del;, since del cannot be less than zero.
4dcf0e4
to
e250f0a
|
Squished and addressed your nit. |
| } | ||
| } | ||
| } | ||
| if del > 0 { |
This comment has been minimized.
This comment has been minimized.
emilio
Aug 20, 2017
Member
nit: no need for the if, that's what I wanted to avoid in the first place :)
| read(array.ptr().offset(i as isize)); | ||
| del += 1; | ||
| } else if del > 0 { | ||
| swap((array.ptr().offset((i - del) as isize) as *mut A::Item).as_mut().unwrap(), (array.ptr().offset(i as isize) as *mut A::Item).as_mut().unwrap()); |
This comment has been minimized.
This comment has been minimized.
emilio
Aug 20, 2017
Member
nit: Can't we just do self.swap(i - del, i)? We implement DerefMut<[A::Item]>.
This comment has been minimized.
This comment has been minimized.
emilio
Aug 20, 2017
Member
Indeed if we do that and avoid the ptr::read, calling truncate() at the end, we can write this just with safe code, right?
|
@emilio Thanks for the review! The code has been greatly simplified and is no longer unsafe. |
|
@bors-servo: r=emilio,jdm |
|
|
Add retain function <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/59) <!-- Reviewable:end -->
|
|
|
More out of curiosity than any kind of dire need, does this project have any kind of regular release cycle? |
|
It is released whenever someone makes a PR that updated the Cargo.toml version. |
|
This didn't occur to me until just now, but we might want to change the |
|
Why would you want to mutate in a retain? It seems like you'd be better off doing for thing in things {
// Mutate thing
}
things.retain(/*closure*/);I like this approach better as it's more clear that there is a side effect happening. |
Putting the mutation into a separate loop might require allocating additional memory to save intermediate state, while just using
This can't be done in two separate loops like the code above, without saving additional state. Even in cases that can be easily separated, iterating over the collection twice instead can be a significant performance penalty. And since the |
|
Alright that all makes sense. The current retain got released in 0.4.3 which still has 0 downloads so if we hurry and yank it we can still fix this. |
|
It might be less hassle to just fix this next time we make a release with breaking changes. |
Xaeroxe commentedAug 17, 2017
•
edited by larsbergstrom
This change is