Fix chunks peek_with_bitmaps panic (#38430)

Anthony Eid and Nia created

This panic only happened in debug builds because of a left shift
overflow. The slice range has bounds between 0 and 128. The 128 case
caused the overflow.

We now do an unbounded shift and a wrapped sub to get the correct
bitmask. If the slice range is 128 left, it should make 1 zero. Then the
wrapped sub would flip all bits, which is expected behavior.

Release Notes:

- N/A

Co-authored-by: Nia <nia@zed.dev>

Change summary

crates/rope/src/rope.rs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

Detailed changes

crates/rope/src/rope.rs 🔗

@@ -784,7 +784,10 @@ impl<'a> Chunks<'a> {
             slice_start..slice_end
         };
 
-        let bitmask = (1u128 << slice_range.end as u128).saturating_sub(1);
+        // slice range has a bounds between 0 and 128 in non test builds
+        // We use a non wrapping sub because we want to overflow in the case where slice_range.end == 128
+        // because that represents a full chunk and the bitmask shouldn't remove anything
+        let bitmask = (1u128.unbounded_shl(slice_range.end as u32)).wrapping_sub(1);
 
         let chars = (chunk.chars() & bitmask) >> slice_range.start;
         let tabs = (chunk.tabs & bitmask) >> slice_range.start;