Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upSafe memcpy for slices ([T]::copy_from_slice) #1419
Conversation
ubsan
added some commits
Dec 19, 2015
bluss
referenced this pull request
Dec 20, 2015
Closed
Tracking issue for `clone_from_slice` stabilization #27750
This comment has been minimized.
This comment has been minimized.
|
Looks good to me. I'd personally prefer only panicking on |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Dec 20, 2015
|
I think it's a good call to have a free function for |
This comment has been minimized.
This comment has been minimized.
|
@Aatch I also don't feel too strongly about this, but the current design does make this specific use nice: // let src: &[T];
let mut dst: [T; N] = unsafe { std::mem::uninitialized() };
std::slice::copy(src, &mut dst); // You know that dst is fully initialized from here on |
This comment has been minimized.
This comment has been minimized.
Dr-Emann
commented
Dec 20, 2015
|
As a note, dlang has special syntax for set and copy, and it only allows arrays of equal size. e.g. auto x = new int[10];
auto y = new int[11];
x[] = 5; // fill x with 5's
y[] = x[]; // Array lengths don't match for copy: 10 != 11 |
eddyb
reviewed
Dec 20, 2015
| However, `std::slice::bytes::copy_memory`, the function I'm basing this on, only | ||
| panics if `dst.len() < src.len()`. So... room for discussion, here. | ||
|
|
||
| These are necessary functions, in the opinion of the author. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I think |
This comment has been minimized.
This comment has been minimized.
|
@Amanieu I definitely prefer |
This comment has been minimized.
This comment has been minimized.
|
@eddyb @Amanieu I don't think there are issues around adding methods to slice types, but I don't personally like having these functions as methods. These feel "right" as free functions (at least, Although, perhaps |
This comment has been minimized.
This comment has been minimized.
|
@ubsan Keep in mind that the main reason for I can see how |
This comment has been minimized.
This comment has been minimized.
|
@eddyb true, for |
Manishearth
reviewed
Dec 20, 2015
| Add one function to `std::slice`. | ||
|
|
||
| ```rust | ||
| pub fn copy<T: Copy>(src: &[T], dst: &mut [T]); |
This comment has been minimized.
This comment has been minimized.
Manishearth
Dec 20, 2015
Member
Could this cause issue when T contains &U? We have to be careful to avoid lifetime lengthening. But I guess variance will fix it.
This comment has been minimized.
This comment has been minimized.
|
Note that free functions are harder to discover doc-wise. The general rust community seems to avoid them in code; though I'm not certain of this. |
This comment has been minimized.
This comment has been minimized.
|
@Manishearth slice.copy(slice2); // which is src? which is dst?
slice.copy_to(slice2); // okay, it's obvious here, but it's kind of ugly
slice.copy_from(slice2); // same as ^
std::slice::copy(slice, slice2); // nice! also, a connection to std::ptr::copy_nonoverlapping here. |
This comment has been minimized.
This comment has been minimized.
|
I think |
This comment has been minimized.
This comment has been minimized.
jFransham
commented
Dec 20, 2015
|
@ubsan equally to your first example: std::slice::copy(slice, slice2); // which is src? which is dst?I think this is what @Manishearth was talking about when he mentioned looking up the docs. It's obvious if you've used memcpy for years but for people new to systems programming it will be confusing. |
This comment has been minimized.
This comment has been minimized.
Not even that, because that convention isn't uniformly followed across programming languages. I think even rust had a deliberately "backwards" memcpy ordering in the past (I think it got fixed in the rush for 1.0 or something) |
This comment has been minimized.
This comment has been minimized.
The order proposed in the RFC is the opposite of void *memcpy(void *restrict dst, const void *restrict src, size_t n);Anyway, in many cases the Rust would look more like: std::slice::copy(&slice, &mut slice2);which makes it pretty clear which argument is source and which is destination. |
tomjakubowski
reviewed
Dec 20, 2015
| ``` | ||
|
|
||
| `fill` loops through slice, setting each member to value. This will lower to a | ||
| memset in all possible cases. It is defined to call `fill` on a slice which has |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ubsan
changed the title
Safe memcpy, memset for slices (std::slice::{ copy, set })
Safe memcpy, memset for slices [T]::{ copy_from, fill }
Dec 20, 2015
ubsan
changed the title
Safe memcpy, memset for slices [T]::{ copy_from, fill }
Safe memcpy, memset for slices ([T]::{ copy_from, fill })
Dec 20, 2015
This comment has been minimized.
This comment has been minimized.
|
@Manishearth @tomjakubowski I polled some people in the rust community, and it seems that generally people don't like my free functions, and they've convinced me, so I've decided to switch to methods. This also means that I've switched to the name |
This comment has been minimized.
This comment has been minimized.
|
Some alternatives that might be worth considering:
a[..] = b[..];This is currently disallowed because [T] is an unsized type.
iter::copy(b.iter(), a.iter_mut());
iter::copy(b.iter().map(|x| x * 2), a.iter_mut());The downside is that this might be getting too generic, and it wouldn't make sense to have the proposed panic semantics when the iterator lengths don't match. |
This comment has been minimized.
This comment has been minimized.
|
As far as iterators go there's not much value (relatively) there because you can write this as a function already. The reason this RfC is important is that currently there's no way to copy/fill slices in safe Rust efficiently. You have to use a for loop and hope the optimizer magicks it. This RfC provides a way to do that. For iterators, a one-line for loop just works and can't be optimized further, so there's much less value there. |
This comment has been minimized.
This comment has been minimized.
|
@ubsan mostly looks good, Small nit: Perhaps |
This comment has been minimized.
This comment has been minimized.
|
@Manishearth Hmm, I can see your argument... I do like @eddyb's suggestion of |
This comment has been minimized.
This comment has been minimized.
|
@ubsan, @bluss If we don't guarantee I guess what I don't understand is that if we don't guarantee |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Jan 22, 2016
|
With Specialization will change the parameters we're looking at here, but we don't know if / when that arrives. |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Jan 22, 2016
|
The |
This comment has been minimized.
This comment has been minimized.
I somewhat disagree with this personally because I think the same argument could be made about
These kinds of conveniences on core types (like slices) feel to me like they're often useful enough to provide. Your point about guaranteeing a That means in terms of naming, however, that we may want both a |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Jan 22, 2016
|
The naive version of the "clone_from_slice" loop produces terrible code and the naive fill loop produces good code. It's good that we have clone_from_slice so that the right way to tickle llvm for an optimized copying is abstracted out into a method. I don't think the pragmatic argument is the only one for clone_from_slice though. I think .fill(x) is a nice API, but it's not as important as .copy_from(). |
This comment has been minimized.
This comment has been minimized.
|
Agreed, it isn't as important. The only reason I also added |
This comment has been minimized.
This comment has been minimized.
|
In the case that |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I would be fine with that. I don't personally see any pressing need for it, and no one else seems to see any pressing need for it. |
ubsan
changed the title
Safe memcpy, memset for slices ([T]::{ copy_from, fill })
Safe memcpy for slices ([T]::copy_from)
Jan 27, 2016
This comment has been minimized.
This comment has been minimized.
|
Yeah, I'm taking out |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
My personal opinion is that this is good to go with the name |
alexcrichton
added
the
final-comment-period
label
Feb 11, 2016
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I don't personally like the name, because it's a very common function (at least in my personal code) to have such a long name. However, I do see the benefit of it in terms of consistency, so I am not opposed to it. I'd just prefer a shorter name. |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Feb 12, 2016
|
Let's get this in. Thanks for pushing it @ubsan (and I like your new avatar). Using this to replace most uses of |
This comment has been minimized.
This comment has been minimized.
|
@bluss thanks :) I needed a new avatar very badly... Yeah, I will be interested in io::Write performance on Debug (I think it uses |
This comment has been minimized.
This comment has been minimized.
|
A couple thoughts:
|
ubsan
changed the title
Safe memcpy for slices ([T]::copy_from)
Safe memcpy for slices ([T]::copy_from_slice)
Feb 13, 2016
This comment has been minimized.
This comment has been minimized.
|
The libs team discussed this RFC during triage yesterday, and the conclusion was to merge this RFC. We discussed the possibility of having Anyway, I shall merge soon. Thanks again for the RFC @ubsan! |
alexcrichton
referenced this pull request
Feb 18, 2016
Closed
Tracking issue for <[T]>::copy_from_slice #31755
alexcrichton
merged commit ea0ad1c
into
rust-lang:master
Feb 18, 2016
bors
added a commit
to rust-lang/rust
that referenced
this pull request
Feb 26, 2016
This comment has been minimized.
This comment has been minimized.
lgvz
commented
Mar 4, 2016
|
FWIW at this point, I'd most definitely prefer the shorter name |
ubsan commentedDec 20, 2015
No description provided.