Adding an `assert!` prevents bounds check elision
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
pub fn run_filter(
input: &[f32],
output: &mut [f32],
) {
assert_eq!(input.len(), output.len());
let len = input.len().min(output.len());
for i in 1..len {
output[i] = input[i-1] + output[i-1];
}
}
I expected all the bounds checks inside the loop to be elided. Since i inside the loop ranges from 1 to min(input.len(), output.len()) and accesses to the slices are done at indices i and i-1, the indices will be in range from 0 to min(input.len(), output.len()), always in bounds.
Instead, as can be seen in this godbolt link, a bounds check is done every iteration of the loop.
If I swap the order of assert and definition of len or remove the assert altogether, the bounds check is successfully elided, also allowing for some loop unrolling.
Seems that adding an assert is somehow preventing optimization here.
Meta
This seems to happen in both stable 1.90 and nightly (rustc version 1.92.0-nightly (975e6c8fe 2025-09-23))
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by compiling the issue's Rust example on stable and nightly, then compare generated assembly with the assert before and after the len definition using the linked Godbolt cases. Trace the compiler optimization path responsible for bounds-check elimination and identify why the assert changes the result. Done means the equivalent bounds checks are eliminated without requiring the workaround, with a regression test covering the example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100