Skip to content

slice: Remove some uses of unsafe in first/last chunk methods #139145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2025

Conversation

okaneco
Copy link
Contributor

@okaneco okaneco commented Mar 30, 2025

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.

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.

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`
@rustbot
Copy link
Collaborator

rustbot commented Mar 30, 2025

r? @Amanieu

rustbot has assigned @Amanieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 30, 2025
} else {
// SAFETY: We manually verified the bounds of the split.
let (first, tail) = unsafe { self.split_at_unchecked(N) };
let Some((first, tail)) = self.split_at_checked(N) else { return None };
Copy link
Member

Choose a reason for hiding this comment

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

The code for all of these can be made more concise by using ?:

Suggested change
let Some((first, tail)) = self.split_at_checked(N) else { return None };
let (first, tail) = self.split_at_checked(N)?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These functions are const fn so I don't believe ? is available to use.

That results in the following error:

error[E0015]: `?` is not allowed on `Option<(&[T], &[T])>` in constant functions
   --> library\core\src\slice\mod.rs:385:29
    |
385 |         let (first, tail) = self.split_at_checked(N)?;
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

Copy link
Member

Choose a reason for hiding this comment

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

Good point! I'd forgotten about that.

@Amanieu
Copy link
Member

Amanieu commented Apr 2, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Apr 2, 2025

📌 Commit 59ca767 has been approved by Amanieu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 2, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 3, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#139080 (Experimental feature gate for `super let`)
 - rust-lang#139145 (slice: Remove some uses of unsafe in first/last chunk methods)
 - rust-lang#139149 (unstable book: document import_trait_associated_functions)
 - rust-lang#139273 (Apply requested API changes to `cell_update`)
 - rust-lang#139282 (rustdoc: make settings checkboxes always square)
 - rust-lang#139283 (Rustc dev guide subtree update)
 - rust-lang#139294 (Fix the `f16`/`f128` feature gates on integer literals)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 3, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#139080 (Experimental feature gate for `super let`)
 - rust-lang#139145 (slice: Remove some uses of unsafe in first/last chunk methods)
 - rust-lang#139149 (unstable book: document import_trait_associated_functions)
 - rust-lang#139273 (Apply requested API changes to `cell_update`)
 - rust-lang#139282 (rustdoc: make settings checkboxes always square)
 - rust-lang#139283 (Rustc dev guide subtree update)
 - rust-lang#139294 (Fix the `f16`/`f128` feature gates on integer literals)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit e332aa8 into rust-lang:master Apr 3, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 3, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 3, 2025
Rollup merge of rust-lang#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.
@okaneco okaneco deleted the safe_splits branch April 3, 2025 19:25
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Apr 8, 2025
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.
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Apr 8, 2025
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#139080 (Experimental feature gate for `super let`)
 - rust-lang#139145 (slice: Remove some uses of unsafe in first/last chunk methods)
 - rust-lang#139149 (unstable book: document import_trait_associated_functions)
 - rust-lang#139273 (Apply requested API changes to `cell_update`)
 - rust-lang#139282 (rustdoc: make settings checkboxes always square)
 - rust-lang#139283 (Rustc dev guide subtree update)
 - rust-lang#139294 (Fix the `f16`/`f128` feature gates on integer literals)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants