-
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
Avoid zero-sized allocs in ThinBox if T and H are both ZSTs. #96642
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
This doesn't touch the public API in any way (aside from fixing the unsoundness in |
To explain why I think that the previous (and current) code is sound despite using aligned read/write for If we consider allocation as returning
(The above is all how the code currently works, although seeing this requires peeking inside the abstractions provided by As it is, the code relies on Anyway, I mostly wanted to write this down, so that I could (possibly) find it in the future. It's essentially unrelated to this patch (beyond, erm, the fact that I broke it in the middle of writing this patch, but fixed it by the end) |
I'm down to review code I'm familiar with still! Just taking a break from the rotation, not reviews in general. Which I guess is my way of saying I want to review this :D |
Looks great, thanks for showing @bors r+ |
📌 Commit 25164b4 has been approved by |
(Sorry, bors missed it the first time, then I typoed your name 😓) @bors r=yaahc |
💡 This pull request was already approved, no need to approve it again.
|
📌 Commit 25164b4 has been approved by |
Avoid zero-sized allocs in ThinBox if T and H are both ZSTs. This was surprisingly tricky, and took longer to get right than expected. `ThinBox` is a surprisingly subtle piece of code. That said, in the end, a lot of this was due to overthinking[^overthink] -- ultimately the fix ended up fairly clean and simple. [^overthink]: Honestly, for a while I was convinced this couldn't be done without allocations or runtime branches in these cases, but that's obviously untrue. Anyway, as a result of spending all that time debugging, I've extended the tests quite a bit, and also added more debug assertions. Many of these helped for subtle bugs I made in the middle (for example, the alloc/drop tracking is because I ended up double-dropping the value in the case where both were ZSTs), they're arguably a bit of overkill at this point, although I imagine they could help in the future too. Anyway, these tests cover a wide range of size/align cases, nd fully pass under miri[^1]. They also do some smoke-check asserting that the value has the correct alignment, although in practice it's totally within the compiler's rights to delete these assertions since we'd have already done UB if they get hit. They have more boilerplate than they really need, but it's not *too* bad on a per-test basis. A notable absence from testing is atypical header types, but at the moment it's impossible to manually implement `Pointee`. It would be really nice to have testing here, since it's not 100% obvious to me that the aligned read/write we use for `H` are correct in the face of arbitrary combinations of `size_of::<H>()`, `align_of::<H>()`, and `align_of::<T>()`. (That said, I spent a while thinking through it and am *pretty* sure it's fine -- I'd just feel... better if we could test some cases for non-ZST headers which have unequal and align). [^1]: Or at least, they pass under miri if I copy the code and tests into a new crate and run miri on it (after making it less stdlibified). Fixes rust-lang#96485. I'd request review `@yaahc,` but I believe you're taking some time away from reviews, so I'll request from the previous PR's reviewer (I think that the context helps, even if the actual change didn't end up being bad here). r? `@joshtriplett`
Rollup of 5 pull requests Successful merges: - rust-lang#96642 (Avoid zero-sized allocs in ThinBox if T and H are both ZSTs.) - rust-lang#97647 (Lazily allocate and initialize pthread locks.) - rust-lang#97715 (Support the `#[expect]` attribute on fn parameters (RFC-2383)) - rust-lang#97716 (Fix reachability analysis for const methods) - rust-lang#97722 (Tighten spans for bad fields in struct deriving `Copy`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This was surprisingly tricky, and took longer to get right than expected.
ThinBox
is a surprisingly subtle piece of code. That said, in the end, a lot of this was due to overthinking1 -- ultimately the fix ended up fairly clean and simple.Anyway, as a result of spending all that time debugging, I've extended the tests quite a bit, and also added more debug assertions. Many of these helped for subtle bugs I made in the middle (for example, the alloc/drop tracking is because I ended up double-dropping the value in the case where both were ZSTs), they're arguably a bit of overkill at this point, although I imagine they could help in the future too.
Anyway, these tests cover a wide range of size/align cases, nd fully pass under miri2. They also do some smoke-check asserting that the value has the correct alignment, although in practice it's totally within the compiler's rights to delete these assertions since we'd have already done UB if they get hit. They have more boilerplate than they really need, but it's not too bad on a per-test basis.
A notable absence from testing is atypical header types, but at the moment it's impossible to manually implement
Pointee
. It would be really nice to have testing here, since it's not 100% obvious to me that the aligned read/write we use forH
are correct in the face of arbitrary combinations ofsize_of::<H>()
,align_of::<H>()
, andalign_of::<T>()
. (That said, I spent a while thinking through it and am pretty sure it's fine -- I'd just feel... better if we could test some cases for non-ZST headers which have unequal and align).Fixes #96485.
I'd request review @yaahc, but I believe you're taking some time away from reviews, so I'll request from the previous PR's reviewer (I think that the context helps, even if the actual change didn't end up being bad here).
r? @joshtriplett
Footnotes
Honestly, for a while I was convinced this couldn't be done without allocations or runtime branches in these cases, but that's obviously untrue. ↩
Or at least, they pass under miri if I copy the code and tests into a new crate and run miri on it (after making it less stdlibified). ↩