Skip to content

Conversation

@rommeld
Copy link

@rommeld rommeld commented Nov 1, 2025

Adds a new lint chunks_exact_to_as_chunks that suggests using as_chunks instead of chunks_exact when the chunk size is a compile-time constant.

changelog: [chunks_exact_to_as_chunks]: Suggest using slice.as_chunks::() when chunks_exact(N) is called with a compile-time constant. This provides better ergonomics and type safety.

fixes #15882

@rustbot rustbot added needs-fcp S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Nov 1, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 1, 2025

r? @Jarcho

rustbot has assigned @Jarcho.
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

This comment has been minimized.

@github-actions
Copy link

github-actions bot commented Nov 1, 2025

Lintcheck changes for 2731771

Lint Added Removed Changed
clippy::chunks_exact_with_const_size 16 0 0

This comment will be updated if you push new changes

Copy link
Contributor

@ada4a ada4a left a comment

Choose a reason for hiding this comment

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

Good start:) Left a couple suggestions

View changes since this review

LL | let mut it = slice.chunks_exact(CHUNK_SIZE);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using `as_chunks::<4>()` for better ergonomics
Copy link
Contributor

Choose a reason for hiding this comment

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

As this example shows, the suggestion replace even named constants with their values. To fix that, build the suggestion using a snippet of arg, to preserve its textual representation:

- format!("consider using `{suggestion}::<{chunk_size}>()` for better ergonomics")
+ let arg_str = snippet(cx, arg.span, "_");
+ format!("consider using `{suggestion}::<{arg_str}>()` for better ergonomics")

Copy link
Author

Choose a reason for hiding this comment

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

Done in 610acda


// Should trigger lint - literal constant
let mut it = slice.chunks_exact(4);
//~^ ERROR: using `chunks_exact` with a constant chunk size
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you could also use the lint name, which is a bit shorter:

Suggested change
//~^ ERROR: using `chunks_exact` with a constant chunk size
//~^ chunks_exact_to_as_chunks

Copy link
Author

Choose a reason for hiding this comment

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

Done in 610acda

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, no, that's not what I meant.. sorry for not articulating myself clearly.

The error message by itself is great, no need to change it. It's just that in the ui-test file, you can specify the error annotation not only as //~^ ERROR: <error message>, but also as //~^ <lint_name> (in your case, //~^ chunks_exact_with_const_size, which makes the test suite much less verbose overall, and so that's the change I was proposing.

Copy link
Author

Choose a reason for hiding this comment

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

I guess I misunderstood, and I hope this hash is correctly implemented and suits your suggestion bc1d010.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that's exactly what I meant:)

/// for chunk in chunks {}
/// ```
#[clippy::version = "1.93.0"]
pub CHUNKS_EXACT_TO_AS_CHUNKS,
Copy link
Contributor

Choose a reason for hiding this comment

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

lint names usually either point out the "bad" pattern used (e.g. ok_expect), or what the pattern could be replaced with (e.g. manual_map). I think yours could use the former scheme, and be called something like chunks_exact_with_const_size

Copy link
Author

Choose a reason for hiding this comment

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

Done in 610acda

"as_chunks"
};

span_lint_and_help(
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be pretty effortlessly switched over to give suggestions, which are quite nice to have. https://doc.rust-lang.org/clippy/development/emitting_lints.html#suggestions-automatic-fixes should help you in that, but don't hesitate to ask if something's unclear

Comment on lines 24 to 29
// Check receiver is slice or array type
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
if !recv_ty.is_slice() && !recv_ty.is_array() {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You want to check for types that can be adjusted to slices, which includes e.g. Vec. For that, you can use TyCtxt::expr_ty_adjusted:

Suggested change
// Check receiver is slice or array type
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
if !recv_ty.is_slice() && !recv_ty.is_array() {
return;
}
// Check if receiver is slice-like
if !cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice() {
return;
}

Copy link
Author

Choose a reason for hiding this comment

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

Done in 1d99b91

Comment on lines 19 to 23
// Check for Rust version
if !msrv.meets(cx, msrvs::AS_CHUNKS) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This check is somewhat expensive, so it's best to perform it towards the end, e.g. after the constant check

Copy link
Author

Choose a reason for hiding this comment

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

Done in 2731771

Suggest using slice.as_chunks::<N>() when chunks_exact(N) is called with a compile-time constant. This provides better ergonomics and type safety.

Fixes rust-lang#15882
Changed example suggestion from const to snippet

Shortend error message

Followed clippy naming conventions
@rommeld rommeld force-pushed the suggest-as-chunks-over-chunks-exact branch from 849dbe8 to 610acda Compare November 4, 2025 18:38
@rustbot
Copy link
Collaborator

rustbot commented Nov 4, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot
Copy link
Collaborator

rustbot commented Nov 4, 2025

⚠️ Warning ⚠️

  • There are issue links (such as #123) in the commit messages of the following commits.
    Please move them to the PR description, to avoid spamming the issues with references to the commit, and so this bot can automatically canonicalize them to avoid issues with subtree.

);
},
(name @ (sym::chunks_exact | sym::chunks_exact_mut), [arg]) => {
chunks_exact_with_const_size::check(cx, expr, recv, arg, name, self.msrv);
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently, the span that the lint points at is the whole method call expression (expr.span) -- as the last result in Lintcheck (https://github.com/rust-lang/rust-clippy/actions/runs/19080004877#user-content-chunks-exact-with-const-size) shows, that might lead to a somewhat confusing diagnostics:

warning: chunks_exact_with_const_size
   --> target/lintcheck/sources/rustc-demangle-0.1.24/src/v0.rs:299:25
    |
299 |           let mut bytes = self
    |  _________________________^
300 | |             .nibbles
301 | |             .as_bytes()
302 | |             .chunks_exact(2)
    | |____________________________^
    |
    = help: consider using `as_chunks::<2>()` for better ergonomics
    = note: `--force-warn clippy::chunks-exact-with-const-size` implied by `--force-warn clippy::all`

You can instead only highlight the method call (in this case, chunks_exact(2), by using call_span, which comes from the call to method_call(expr) above (line 13) -- see filter_map_bool_then for a (somewhat) simple example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-fcp S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggest as_chunks when people use chunks_exact with a constant length

4 participants