-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
define copy_within on slices #53652
define copy_within on slices #53652
Conversation
r? @Kimundi (rust_highfive has picked a reviewer for you, use r? to override) |
6f3ee2d
to
063bfa7
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
063bfa7
to
cd69d40
Compare
I added |
Seems like it needs |
cd69d40
to
3c5de8e
Compare
@BurntPizza thanks for catching that. I've amended and rebased. |
3c5de8e
to
76e3653
Compare
Safety question not necessarily specific to this PR: Indexing into a slice relies on |
76e3653
to
bda5237
Compare
I've published this function as a standalone crate in the meantime: https://crates.io/crates/copy_in_place |
Ping from triage @Kimundi / @rust-lang/libs: This PR requires your review. |
Thanks for the PR! The API here looks pretty good to me, although I might suggest |
With three pub fn copy_in_place(&mut self, src: Range<usize>, dest: RangeFrom<usize>) where T: Copy {
assert!(src.end >= src.start);
let count = src.end - src.start;
// …
} bytes.copy_in_place(1..5, 8..) |
The name: I noticed there was some precedent along the lines of The API: Agreed that it's hard to remember. I think the one major advantage that the current approach has going for it is that it's a pretty direct clone of Tracking issue: @alexcrichton how does that work? Would I file one, or would someone on the core team? Before or after this PR lands? |
I guess another option would be to define some kind of arg struct, so that the caller is forced to name each field that it's passing in. That could help readability, but I don't know if there's precedent for it in the standard library. It would also be unnecessarily verbose in the case where the caller already has variables with decent names. Or perhaps the src and dest args could live in a tuple, just to set them apart? That would be kind of quirky though. |
But Regarding a generic parameter with |
I opened a PR on my crate implementation to take a look at what a range argument would look like. It seems viable. The upside is that the argument type's a lot more visible. The downside is that a caller with a |
@alexcrichton could you say more about how tracking issues work? Should I file one now, or wait until we have a little more consensus on the API here? |
@oconnor663 oh sure yeah, so for us a tracking issue is created whenever we merge an unstable feature. So to land this PR we'll want a tracking issue which lists out the various design questions and such. |
bda5237
to
c4ec3ae
Compare
I've opened a tracking issue (#54236), updated the issue number referenced inline in this PR, and rebased. |
src/libcore/slice/mod.rs
Outdated
assert!(dest <= self.len() - count); | ||
unsafe { | ||
let src_ptr = self.get_unchecked(src) as *const T; | ||
let dest_ptr = self.get_unchecked_mut(dest) as *mut T; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You shouldn't need to cast these; they'll coerce just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think without the casts this fails the borrow checker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes, you're of course right. I was thinking of when they're not in variables:
ptr::copy(
slice.get_unchecked(src),
slice.get_unchecked_mut(dest),
count,
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh gotcha. Do you think that version would be better style? I'd be happy with either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no strong opinion, other than that I do like avoiding as
, especially to *mut
.
Maybe keep the variables, but coerce instead of casting?
let src_ptr: *const T = self.get_unchecked(src);
let dest_ptr: *mut T = self.get_unchecked_mut(dest);
Would we only suggest this when things can overlap? Or would this replace using split_at_mut when the sides cannot overlap? If I'm reading it right, the one example in the docs doesn't need this method: let (a, b) = bytes.split_at_mut(8);
b[..4].copy_from_slice(a[1..5]); |
I'm not sure. On the one hand, the two-liner above would become a one-liner: bytes.copy_in_place(9, 0, 4);
// Or with the API SimonSapin suggested:
bytes.copy_in_place(9..13, 0); On the other hand, I think |
c4ec3ae
to
cd4de8f
Compare
I've gotten rid of pointer casts as @scottmcm suggested, switched to @SimonSapin's suggested API, and rebased again. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
Looks good to me! I think there's some tidy/style issues though? |
cd4de8f
to
7dd3a24
Compare
Line length should be fixed now. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
7dd3a24
to
0cc47aa
Compare
Very silly copy-paste-o on my part. Should be fixed. I also decided I like @alexcrichton's name suggestion |
0cc47aa
to
9e73b45
Compare
Thanks! Sorry I forgot to mention earlier, but could some semi-exhaustive tests be added for this as well? With |
This is a safe wrapper around ptr::copy, for regions within a single slice. Previously, safe in-place copying was only available as a side effect of Vec::drain.
8037329
to
bf834cc
Compare
I've added some tests, which are hopefully about to pass Travis. I could add more? |
bf834cc
to
d0e59f5
Compare
@bors: r+ Thanks! |
📌 Commit d0e59f5 has been approved by |
…chton define copy_within on slices This is a safe wrapper around `ptr::copy`, for regions within a single slice. Previously, safe in-place copying was only available as a side effect of `Vec::drain`. I've wanted this API a couple times in the past, and I figured I'd just whip up a PR to help discuss it. It's possible something like this exists elsewhere and I just missed it. It might also be a big enough addition to warrant an RFC, I'm not sure.
Rollup of 10 pull requests Successful merges: - #53652 (define copy_within on slices) - #54261 (Make `dyn` a keyword in the 2018 edition) - #54317 (Implement the dbg!(..) macro) - #54323 (rustbuild: drop color handling) - #54371 (add -Zui-testing to rustdoc) - #54374 (Make 'proc_macro::MultiSpan' public.) - #54402 (Use no_default_libraries for all NetBSD flavors) - #54412 (add applicability to span_suggestion call) - #54413 (Add UI test for deref recursion limit printing twice) - #54422 (Simplify slice's first(_mut) and last(_mut) with get)
…chton define copy_within on slices This is a safe wrapper around `ptr::copy`, for regions within a single slice. Previously, safe in-place copying was only available as a side effect of `Vec::drain`. I've wanted this API a couple times in the past, and I figured I'd just whip up a PR to help discuss it. It's possible something like this exists elsewhere and I just missed it. It might also be a big enough addition to warrant an RFC, I'm not sure.
Rollup of 16 pull requests Successful merges: - #53652 (define copy_within on slices) - #54261 (Make `dyn` a keyword in the 2018 edition) - #54280 (remove (more) CAS API from Atomic* types where not natively supported) - #54323 (rustbuild: drop color handling) - #54350 (Support specifying edition in doc test) - #54370 (Improve handling of type bounds in `bit_set.rs`.) - #54371 (add -Zui-testing to rustdoc) - #54374 (Make 'proc_macro::MultiSpan' public.) - #54402 (Use no_default_libraries for all NetBSD flavors) - #54409 (Detect `for _ in in bar {}` typo) - #54412 (add applicability to span_suggestion call) - #54413 (Add UI test for deref recursion limit printing twice) - #54415 (parser: Tweak function parameter parsing to avoid rollback on succesfull path) - #54420 (Compress `Liveness` data some more.) - #54422 (Simplify slice's first(_mut) and last(_mut) with get) - #54446 (Unify christianpoveda's emails) Failed merges: - #54058 (Introduce the partition_dedup/by/by_key methods for slices) r? @ghost
Rollup of 16 pull requests Successful merges: - #53652 (define copy_within on slices) - #54261 (Make `dyn` a keyword in the 2018 edition) - #54280 (remove (more) CAS API from Atomic* types where not natively supported) - #54323 (rustbuild: drop color handling) - #54350 (Support specifying edition in doc test) - #54370 (Improve handling of type bounds in `bit_set.rs`.) - #54371 (add -Zui-testing to rustdoc) - #54374 (Make 'proc_macro::MultiSpan' public.) - #54402 (Use no_default_libraries for all NetBSD flavors) - #54409 (Detect `for _ in in bar {}` typo) - #54412 (add applicability to span_suggestion call) - #54413 (Add UI test for deref recursion limit printing twice) - #54415 (parser: Tweak function parameter parsing to avoid rollback on succesfull path) - #54420 (Compress `Liveness` data some more.) - #54422 (Simplify slice's first(_mut) and last(_mut) with get) - #54446 (Unify christianpoveda's emails) Failed merges: - #54058 (Introduce the partition_dedup/by/by_key methods for slices) r? @ghost
This is a safe wrapper around
ptr::copy
, for regions within a single slice. Previously, safe in-place copying was only available as a side effect ofVec::drain
.I've wanted this API a couple times in the past, and I figured I'd just whip up a PR to help discuss it. It's possible something like this exists elsewhere and I just missed it. It might also be a big enough addition to warrant an RFC, I'm not sure.