Skip to content

Conversation

@BD103
Copy link
Member

@BD103 BD103 commented Nov 13, 2025

Objective

  • Although unsafe, ThinSlicePtr::get() doesn't signal that it doesn't perform bounds checking unless you are familiar with the API.
  • ThinSlicePtr::get() takes self, not &self, meaning it consumes the ThinSlicePtr each time get() is called. This does not match the behavior of slice.get(), which takes &self.
    • This small issue was hidden by the fact that ThinSlicePtr implements Copy. This isn't a large issue because it all compiles down to the same machine code, but there's no point to get() requiring self.
  • ThinSlicePtr could use better documentation, and could be improved a little in some areas.

Solution

  • Rename ThinSlicePtr::get() to get_unchecked(), making the API mirror slice.get_unchecked(). The old get() is kept as a deprecated method, to be removed in 1.19.0.
  • Make the new slice.get_unchecked() take &self rather than self.
  • Add more documentation and slightly re-arrange code, while maintaining original behavior.

Testing

  • Any unintentional changes should be caught by the Rust Compiler and Miri!

`debug_assert!()` already handles this for us!
This makes it more clear to a reviewer looking over code that the `get()` is not bounds checked. It also is consistent with  `slice::get_unchecked()`.
It wasn't caught previously because `ThinSlicePtr` is `Copy`, but we don't want to clone the pointer every time we dereference it. Additionally, this makes the method consistent with `slice::get_unchecked()`.
@BD103 BD103 added C-Docs An addition or correction to our documentation C-Code-Quality A section of code that is hard to understand or change M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide A-Pointers Relating to Bevy pointer abstractions D-Straightforward Simple bug fixes and API improvements, docs, test and examples D-Unsafe Touches with unsafe code in some way S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Nov 13, 2025
@BD103
Copy link
Member Author

BD103 commented Nov 13, 2025

This is my first time writing a migration guide using the new system. (Crazy, right?!) Let me know if I did anything wrong :)

#[inline]
/// Indexes the slice without doing bounds checks
pub unsafe fn get_unchecked(&self, index: usize) -> &'a T {
debug_assert!(index < self.len, "tried to index out-of-bounds of a slice");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking comment: I noticed you removed the #[cfg(debug_assertions)] line that was above this previously (in the deprecated function). With debug_assert!, as far as I can read from documentation, that line is actually not needed, right? It seems like there are other places in the codebase where this redundant line is placed above a debug_assert!

(new here and new to Rust!)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! I removed the #[cfg(...)] because it was redundant. The reason is because debug_assert!() actually compiles down to:

if cfg!(debug_assertions) {
    assert!(...);
}

Adding #[cfg(debug_assertions)] to this if statement is redundant because we'd be checking if debug_assertions is enabled twice!

It seems like there are other places in the codebase where this redundant line is placed above a debug_assert!

Where else did you find cases like this? I can open up a follow-up issue for getting rid of them too. :)

Copy link

@kfc35 kfc35 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this link works for you: https://github.com/search?q=repo%3Abevyengine%2Fbevy+%22%23%5Bcfg%28debug_assertions%29%5D%22+debug_assert%21&type=code (if not, you can search for usages via typing repo:bevyengine/bevy "#[cfg(debug_assertions)]" debug_assert!) in the search bar). You may have to expand the matches per file since GitHub likes to consolidate them.

It seems there are a few other places, although in my search I did find a useful comment in unsafe_world_cell.rs above one usage:

        // This annotation is needed because the
        // allows_mutable_access field doesn't exist otherwise.
        // Kinda weird, since debug_assert would never be called,
        // but CI complained in https://github.com/bevyengine/bevy/pull/17393

So I wonder if your pull request might run into this issue because self.len is also only defined in the debug config? Something to keep in mind if the CI complains about it

Copy link
Member Author

@BD103 BD103 Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that's a really good point. I just tested it and my branch fails to check with --release:

error[E0609]: no field `len` on type `&ThinSlicePtr<'a, T>`
    --> crates/bevy_ptr/src/lib.rs:1097:36
     |
1097 |         debug_assert!(index < self.len, "tried to index out-of-bounds of a slice");
     |                                    ^^^ unknown field
     |
     = note: available fields are: `ptr`, `_marker`

I replaced debug_assert!() with a #[cfg(debug_assertions)] assert!() call instead, which does the same thing in debug mode but will skip compiling index < self.len in release mode. Thanks for pointing this out!

Copy link

@kfc35 kfc35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New here so my approval may not mean as much, but it LGTM!

@BD103 BD103 added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Nov 13, 2025
@BD103 BD103 added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Nov 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Pointers Relating to Bevy pointer abstractions C-Code-Quality A section of code that is hard to understand or change C-Docs An addition or correction to our documentation D-Straightforward Simple bug fixes and API improvements, docs, test and examples D-Unsafe Touches with unsafe code in some way M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants