Added From<Vec<NonZeroU8>> for CString#64069
Conversation
|
(rust_highfive has picked a reviewer for you, use r? to override) |
|
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 |
|
Perhaps there could be a method to return the nonzero bytes as a slice as well? |
Sounds reasonable to me. That should be its own PR though, as that can be feature-gated for some time while trait implementations are instantly stable. |
|
Ping from triage Thanks. |
Centril
left a comment
There was a problem hiding this comment.
Mostly just some nits...
There was a problem hiding this comment.
what's with the line break here?
There was a problem hiding this comment.
Woops, my own Rust style leaked here (Out of topic: I see pub and unsafe, among others, as markers, hence the logic of them being on an extra line rather than on the same line, in the same vein as other #[meta] attributes)
There was a problem hiding this comment.
Why not check Layout::array::<T / U>().unwrap() against each other?
There was a problem hiding this comment.
| /// `Layout<[U; cap]>` (for the allocator) | |
| /// `Layout<[U; cap]>` (for the allocator). |
hanna-kruppe
left a comment
There was a problem hiding this comment.
Soundness argument seems fine to me, just some nits.
There was a problem hiding this comment.
Nit: strike the hypothetical. I am reasonably sure you do need the safety invariant here. Most operations on vectors don't assert validity of any elements except perhaps the ones they move into or out of the vec. Of course, a Vec<T> is only safe if elements 0..len are safe at T, so the soundness argument can rest on that plus the safety/validity (same thing) of the NonZeroU8.
(Insert standard disclaimer about all of these details being not yet ratified here.)
There was a problem hiding this comment.
You're right, I will remove the part between brackets then (I'm still glad I put it, it is good to clearly think about these things before merging).
There was a problem hiding this comment.
A type annotation won't hurt here IMO.
There was a problem hiding this comment.
The first check is an assert since it is expected to be easily optimized out (only const / compile-time information here).
On the other hand, the check involving Layout::array cannot be const, since it involves the runtime value of the vector capacity.
That being said, I expect Layout<T> == Layout<U> to imply that for all N: usize, Layout<[T; N]> == Layout<[U; N]>.
If this were not to be correct / guaranteed by the language, this debug assertion could be upgraded to a normal assert!; in this case however, the function is only used with the monomorphisation to T = NonZeroU8 and V = u8, which does not require such check at runtime.
There was a problem hiding this comment.
I think it would be a serious bug in Layout::array if this is not given... its comparison test would fail to take something into account, or so.
Not sure if this check is worth the clutter it introduces.
There was a problem hiding this comment.
Great! I will remove the debug_assert! involving the Layout::array check
755fe39 to
b32aec7
Compare
|
I'm afraid my Rust inbox is swamped, I won't be able to review this -- I can take a glance, but don't have time to do a full review. Any takers? (Also is there some way to tell bors "sorry, not me", if I don't know whom else to assign?) |
There was a problem hiding this comment.
ManuallyDrop implements Deref; why is the intermediate let v: &mut Vec<T> = ... needed?
There was a problem hiding this comment.
It's just me being (overly?) cautious with type inference / method resolution within unsafe code , so I wanted to have that Deref be very explicit.
|
Going to re-assign to @rkruppe as they appear to have done some review here but feel free to reassign to someone else if you don't feel confident reviewing this. |
|
I'm fine with reviewing this. Will take another close look later for due digilence but from what I recall this should be in good shape. I think some @rust-lang/libs sign-off is also required since this is a new insta-stable API addition. |
|
I've nominated to get someone from T-libs to kick off an FCP merge here |
|
I checked Kimundi's box per rust-lang/team@bfbf48f. |
|
🔔 This is now entering its final comment period, as per the review above. 🔔 |
|
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
|
Did we come to a decision on the multiple But thanks for working on this @danielhenrymantilla! Would you like to squash some of your commits down before merging? |
Updated tracking issue number Added safeguards for transmute_vec potentially being factored out elsewhere Clarified comment about avoiding mem::forget Removed unneeded unstable guard Added back a stability annotation for CI Minor documentation improvements Thanks to @Centril's code review Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com> Improved layout checks, type annotations and removed unaccurate comment Removed unnecessary check on array layout Adapt the stability annotation to the new 1.41 milestone Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com> Simplify the implementation. Use `Vec::into_raw_parts` instead of a manual implementation of `Vec::transmute`. If `Vec::into_raw_parts` uses `NonNull` instead, then the code here will need to be adjusted to take it into account (issue rust-lang#65816) Reduce the whitespace of safety comments
8a9725a to
60274a9
Compare
|
I did have a preference for the split blocks, but I seem to be at a minority here, so I have merged the There should be nothing blocking the merge, now 🙂 |
|
r? @KodrAus |
|
@bors r+ |
|
📌 Commit 60274a9 has been approved by |
…_from_vec_of_nonzerou8, r=KodrAus Added From<Vec<NonZeroU8>> for CString Added a `From<Vec<NonZeroU8>>` `impl` for `CString` # Rationale - `CString::from_vec_unchecked` is a subtle function, that makes `unsafe` code harder to audit when the generated `Vec`'s creation is non-trivial. This `impl` allows to write safer `unsafe` code thanks to the very explicit semantics of the `Vec<NonZeroU8>` type. - One such situation is when trying to `.read()` a `CString`, see issue rust-lang#59229. - this lead to a PR: rust-lang#59314, that was closed for being too specific / narrow (it only targetted being able to `.read()` a `CString`, when this pattern could have been generalized). - the issue suggested another route, based on `From<Vec<NonZeroU8>>`, which is indeed a less general and more concise code pattern. - quoting @Shnatsel: - > For me the main thing about making this safe is simplifying auditing - people have spent like an hour looking at just this one unsafe block in libflate because it's not clear what exactly is unchecked, so you have to look it up when auditing anyway. This has distracted us from much more serious memory safety issues the library had. Having this trivial impl in stdlib would turn this into safe code with compiler more or less guaranteeing that it's fine, and save anyone auditing the code a whole lot of time.
Rollup of 6 pull requests Successful merges: - #64069 (Added From<Vec<NonZeroU8>> for CString) - #66721 (implement LowerExp and UpperExp for integers) - #69106 (Fix std::fs::copy on WASI target) - #69154 (Avoid calling `fn_sig` on closures) - #69166 (Check `has_typeck_tables` before calling `typeck_tables_of`) - #69180 (Suggest a comma if a struct initializer field fails to parse) Failed merges: r? @ghost
Added a
From<Vec<NonZeroU8>>implforCStringRationale
CString::from_vec_uncheckedis a subtle function, that makesunsafecode harder to audit when the generatedVec's creation is non-trivial. Thisimplallows to write saferunsafecode thanks to the very explicit semantics of theVec<NonZeroU8>type.One such situation is when trying to
.read()aCString, see issue Reading a CString safely without overhead from Read #59229.this lead to a PR: Implement CString::from_reader #59314, that was closed for being too specific / narrow (it only targetted being able to
.read()aCString, when this pattern could have been generalized).the issue suggested another route, based on
From<Vec<NonZeroU8>>, which is indeed a less general and more concise code pattern.quoting @Shnatsel: