Rollup merge of #139145 - okaneco:safe_splits, r=Amanieu
slice: Remove some uses of unsafe in first/last chunk methods Remove unsafe `split_at_unchecked` and `split_at_mut_unchecked` in some slice `split_first_chunk`/`split_last_chunk` methods. Replace those calls with the safe `split_at` and `split_at_checked` where applicable. Add codegen tests to check for no panics when calculating the last chunk index using `checked_sub` and `split_at`. Better viewed with whitespace disabled in diff view --- The unchecked calls are mostly manual implementations of the safe methods, but with the safety condition negated from `mid <= len` to `len < mid`. ```rust if self.len() < N { None } else { // SAFETY: We manually verified the bounds of the split. let (first, tail) = unsafe { self.split_at_unchecked(N) }; // Or for the last_chunk methods let (init, last) = unsafe { self.split_at_unchecked(self.len() - N) }; ``` Unsafe is still needed for the pointer array casts. Their safety comments are unmodified.
This commit is contained in:
commit
e332aa89a7
2 changed files with 57 additions and 59 deletions
24
tests/codegen/slice-split-at.rs
Normal file
24
tests/codegen/slice-split-at.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Check that no panic is generated in `split_at` when calculating the index for
|
||||
// the tail chunk using `checked_sub`.
|
||||
//
|
||||
// Tests written for refactored implementations of:
|
||||
// `<[T]>::{split_last_chunk, split_last_chunk_mut, last_chunk, last_chunk_mut}`
|
||||
|
||||
// CHECK-LABEL: @split_at_last_chunk
|
||||
#[no_mangle]
|
||||
pub fn split_at_last_chunk(s: &[u8], chunk_size: usize) -> Option<(&[u8], &[u8])> {
|
||||
// CHECK-NOT: panic
|
||||
let Some(index) = s.len().checked_sub(chunk_size) else { return None };
|
||||
Some(s.split_at(index))
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @split_at_mut_last_chunk
|
||||
#[no_mangle]
|
||||
pub fn split_at_mut_last_chunk(s: &mut [u8], chunk_size: usize) -> Option<(&mut [u8], &mut [u8])> {
|
||||
// CHECK-NOT: panic
|
||||
let Some(index) = s.len().checked_sub(chunk_size) else { return None };
|
||||
Some(s.split_at_mut(index))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue