Repository navigation
cranelift-entity: remove unused get_raw_mut and into_boxed_slice - #15159
Conversation
`PrimaryMap::into_boxed_slice` turned its `Box<[V]>` into a raw pointer only to rebuild the same `Box` in the unsafe `BoxedSlice::from_raw`. Build the `BoxedSlice` from the `Box` directly instead, and remove `from_raw`, which has no other users in this repository. `PrimaryMap::get_raw_mut` already checks that the index is in bounds, so `wrapping_add` gives the same pointer as `add` without `unsafe`. The crate now has no `unsafe` code, so add `#![forbid(unsafe_code)]`.
| unsafe { Some(self.elems.as_mut_ptr().add(k.index())) } | ||
| // The index is in bounds per the check above, so `wrapping_add` | ||
| // produces the same pointer that `add` would, without `unsafe`. | ||
| Some(self.elems.as_mut_ptr().wrapping_add(k.index())) |
There was a problem hiding this comment.
This would likely cause LLVM to do a worse job at optimizing as the result of wrapping_add is not known to be in-bounds. And if the add was UB, the user would end up with UB anyway when dereferencing this pointer.
There was a problem hiding this comment.
You're right — and it turns out nothing calls it. I grepped the whole workspace: the only references were its own unit test and the TryPrimaryMap::get_raw_mut wrapper in wasmtime-environ, which also has no callers. I've removed both (and the test) in a follow-up commit, so the wrapping_add is gone entirely and forbid(unsafe_code) no longer depends on it. cargo test -p cranelift-entity and cargo check -p wasmtime-environ pass.
| pub fn into_boxed_slice(self) -> BoxedSlice<K, V> { | ||
| unsafe { BoxedSlice::<K, V>::from_raw(Box::<[V]>::into_raw(self.elems.into_boxed_slice())) } | ||
| BoxedSlice::new(self.elems.into_boxed_slice()) | ||
| } |
There was a problem hiding this comment.
Is this method actually used anywhere?
There was a problem hiding this comment.
It isn't. The only callers in the workspace were the BoxedSlice tests in this crate; every other into_boxed_slice hit is the Vec/TryVec method on unrelated types. I've removed PrimaryMap::into_boxed_slice, and the tests now build the slice directly through the pub(crate) BoxedSlice::new.
That leaves BoxedSlice itself with no users and no way to construct one from outside the crate. Do you want me to remove BoxedSlice entirely in this PR as well, or keep it?
There was a problem hiding this comment.
Went ahead with this: BoxedSlice is removed entirely in 7ddf528. After into_boxed_slice was deleted, BoxedSlice::new had no callers left, and CI (which builds with -D warnings) failed on the dead code, cascading into the dependent check and test jobs, so keeping the type was not viable. Locally, cargo check -p cranelift-entity --all-targets with -D warnings is clean, the tests pass (52 + 2; the seven dropped tests were BoxedSlice's own), and the crate is rustfmt-clean. Happy to restore the type if you would rather keep it.
Per review: wrapping_add in get_raw_mut loses the in-bounds information LLVM needs, and if the add were UB the dereference would be too. Neither get_raw_mut (including the TryPrimaryMap wrapper in wasmtime-environ) nor PrimaryMap::into_boxed_slice has any caller in the workspace, so remove them instead. The BoxedSlice tests now build the slice directly through the pub(crate) constructor. With get_raw_mut gone, forbid(unsafe_code) no longer relies on the wrapping_add workaround.
fitzgen
left a comment
There was a problem hiding this comment.
Is there some specific motivation here? I feel like this PR is missing context. I don't think we necessarily want to forbid(unsafe_code), there are valid reasons we might want to use unsafe in this crate in the future.
unsafe codeget_raw_mut and into_boxed_slice
|
Fair question, and sorry for the missing context — I should have written this in the description from the start. The motivation is honestly pretty modest. I've been looking for places where On If even the trimmed-down version isn't something you want, please feel free to close this — no hard feelings. |
Per fitzgen's review: the crate may legitimately want unsafe in the future, and forbidding it at the crate level is stronger than this change needs. The crate currently compiles without any unsafe either way; this keeps only the removal of the two unused methods.
|
@b84330808 can you clarify whether your interactions here are abiding by the project's AI policy? |
|
Yes, happy to clarify. I'm directing this work myself and I review what goes in before anything is submitted. AI tools are part of my process, but there is no unattended agent acting here — the changes, the description and these replies are mine to answer for, and I can walk through the diff if that's useful (it's a small one: two methods with no callers in the workspace, plus their tests). The missing motivation up front was my oversight; the description has it now. I also took your point on |
cfallin
left a comment
There was a problem hiding this comment.
The DCE seems fine to me; this is very old code that probably was written as a generic data structure library before most of Cranelift+Wasmtime grew up around it and solidified our usage patterns.
Agreed with Nick that we don't want to forbid unsafe code; passively reducing it (if free) is always great though.
Just one nit below re: formatting. Thanks!
| Err(slice::GetDisjointMutError::IndexOutOfBounds) | ||
| ); | ||
| } | ||
|
|
There was a problem hiding this comment.
Fixed in 860dab5 — thanks, that was left over from removing the test.
There was a problem hiding this comment.
Also ran rustfmt over the crate and fixed a second stray blank line of the same kind at the end of the impl block (e52e0eb). The crate is rustfmt-clean now.
With PrimaryMap::into_boxed_slice gone, BoxedSlice::new has no callers left and CI (-D warnings) fails on the dead code, which also cascades into the dependent check/test jobs. As suggested in review, remove the type entirely.
|
Thanks; it looks like you have another rustfmt error with another stray line. |
Left over from removing TryPrimaryMap::get_raw_mut; the blank line before the impl block's closing brace is what the rustfmt CI check flags. The other files in this PR check out clean.
|
Fixed in b33ef57 — you were right, there was one more. It was in |
This removes two methods in
cranelift-entitywhoseunsafecode has no callers left in the workspace:PrimaryMap::get_raw_mut— only referenced by its own unit test and by an equally unused wrapper inwasmtime-environ(TryPrimaryMap::get_raw_mut); both are removed. This also addresses bjorn3's point on the earlier revision: thewrapping_addthere had no in-bounds guarantee to lean on, so the sound thing is for the method not to exist.PrimaryMap::into_boxed_slice— only used by theBoxedSlicetests; they now constructBoxedSlicedirectly through itspub(crate)constructor.Motivation: reducing the
unsafesurface where the code is dead anyway. There is no bug behind this — the methods were not called, they just carriedunsafecontracts for no benefit. This kind of unsafe-reduction is also the class of change covered by Google's Patch Rewards program for OSS-Fuzz projects (Tier 2 hardening), which is part of why I went looking for it.An earlier version of this PR also added
#![forbid(unsafe_code)]to the crate; I removed that again after fitzgen's review, since the crate may legitimately wantunsafein the future.Testing:
cargo test -p cranelift-entity— 59 unit tests and 2 doc tests pass;cargo check -p wasmtime-environpasses.Open question from the review thread:
BoxedSliceitself now has no users and cannot be constructed from outside the crate. I'm happy to remove it in this PR too if the maintainers want that.