Uh oh!
There was an error while loading. Please reload this page.
Add {String,Vec}::into_raw_parts - #65705
Conversation
rust-highfive
commented
Oct 22, 2019
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
shepmaster
commented
Oct 22, 2019
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
rust-highfive
commented
Oct 22, 2019
Your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. 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 |
shepmaster
commented
Oct 22, 2019
I believe I've addressed the first round of review comments, thanks! |
Uh oh!
There was an error while loading. Please reload this page.
RalfJung
commented
Oct 22, 2019
LGTM! But let's wait for someone from @rust-lang/libs to also take a look. |
SimonSapin
commented
Oct 22, 2019
What motivates this? Why is it needed or useful when |
rust-highfive
commented
Oct 22, 2019
Your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. 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 |
Lokathor
commented
Oct 22, 2019
It's strikingly easy to get vec transmutation wrong. Just using the methods you listed in the wrong order is UB, for example. So this lets you correctly dismantle a Vec into the parts that you need to use with |
scottmcm
commented
Oct 23, 2019
Personally I like this -- I always have the same sort of wonders as the things that Ralf was commenting about when I do this, and getting things back in the same order as |
SimonSapin
commented
Oct 23, 2019
Could you provide code examples that are UB with an explanation why? This is the same question as in rust-lang/rfcs#2756 (comment) about
I’m not entirely opposed to having this method. But it’s not obvious what problem(s) it solves, so I think it’s important to have those problems documented in details (ideally in the method’s doc-comment), so that that knowledge is not just in the collective mind of people who happen to have participated in a previous discussion. |
Lokathor
commented
Oct 23, 2019
I... defer to @RalfJung to answer that one >_> I do not remember the details well enough to be confident in saying at all. |
@SimonSapin See rust-lang/rust-clippy#4484 and #64073 for some context. The only blessed way to "transmute" a The argument "why is this useful when you can already do this right now by calling 5 other functions in a row" would kill the vast majority of recent libstd additions...
|
SimonSapin
commented
Oct 23, 2019
It’s still not clear to me how exactly things can go wrong or what part would be UB. Again I’m not arguing against adding this method, only for proper documentation (not just in GitHub threads) of all those issues. |
RalfJung
commented
Oct 23, 2019
See #62553 (comment) and #65705 (comment). |
The original case started in Deserialize a Vec<Foobar> as Vec directly when Foobar has exactly one field. There, I effectively did: structFoobarContainer<T>{values:Vec<T>,}#[repr(transparent)]structFoobar<T>{value:T,}let input:Vec<Foobar<T>> = unimplemented!();let output:Vec<T> = mem::transmute(input);Only by a whim of chance did I think to ask if that was safe and learned it was not (as That currently looks like: letmut v:Vec<Foobar<T>> = unimplemented!();let values = unsafe{let data = v.as_mut_ptr()as*mutT;let len = v.len();let cap = v.capacity();
std::mem::forget(v);Vec::from_raw_parts(data, len, cap)};With this new feature, it can look like let v:Vec<Foobar<T>> = unimplemented!();let values = unsafe{let(data, len, cap) = v.into_raw_parts();Vec::from_raw_parts(data as*mutT, len, cap)};That specific example is intended to be expressed in the example for
I agree with @RalfJung's points above
They are certainly motivated by similar concerns (I think the RFC may have even been opened due to the Clippy issue). I believe that there's some amount of benefit to both. If I understand it correctly, unsafefntransmute<U>(self) -> Vec<U>{let(ptr, len, cap) = self.into_raw_parts();let ptr = mem::transmute::<*mutT,*mutU>(ptr);Vec::from_raw_parts(ptr, len, cap)}Then the original example would be letmut v:Vec<Foobar<T>> = unimplemented!();let values:Vec<T> = unsafe{ v.transmute()};Thanks for trying to ensure high-quality for standard library functions! |
SimonSapin
commented
Oct 25, 2019
Alright. I’d like to accept this PR, with a tracking issue and some docs improvements:
I feel that something about this should maybe be part of the docs, but I’m not sure how to phrase it or if it really belongs there. @RalfJung what do you think? |
Centril
commented
Oct 25, 2019
|
Is it worth adding an example of using the raw parts of the let ascii_case_difference = b'a' - b'A';for idx in0..len {unsafe{*ptr.add(idx) -= ascii_case_difference;}}But there's |
shepmaster
commented
Oct 25, 2019
Should these functions be associated functions like |
Lokathor
commented
Oct 25, 2019
Box does that to avoid deref conflicts, I don't think it's necessary here. |
SimonSapin
commented
Oct 25, 2019
Right, if
|
SimonSapin
commented
Oct 25, 2019
Looks good, thanks! @bors r+ |
bors
commented
Oct 25, 2019
📌 Commit 6600cf6 has been approved by |
Add {String,Vec}::into_raw_parts
Aspects to address:
- [x] Create a tracking issue
- rust-lang#65816Rollup of 7 pull requests Successful merges: - #63810 (Make <*const/mut T>::offset_from `const fn`) - #65705 (Add {String,Vec}::into_raw_parts) - #65749 (Insurance policy in case `iter.size_hint()` lies.) - #65799 (Fill tracking issue number for `array_value_iter`) - #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.) - #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().) - #65810 (SGX: Clear additional flag on enclave entry) Failed merges: r? @ghost
shepmaster
commented
Oct 25, 2019
I was mostly asking for consistency between these conceptually similar ideas, not because of an intrinsic need. |
Add {String,Vec}::into_raw_parts
Aspects to address:
- [x] Create a tracking issue
- rust-lang#65816RalfJung
commented
Oct 25, 2019
(That was re: avoiding |
Rollup of 6 pull requests Successful merges: - #65705 (Add {String,Vec}::into_raw_parts) - #65749 (Insurance policy in case `iter.size_hint()` lies.) - #65799 (Fill tracking issue number for `array_value_iter`) - #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.) - #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().) - #65810 (SGX: Clear additional flag on enclave entry) Failed merges: r? @ghost
Aspects to address:
vec_into_raw_parts#65816