rust-lang / rust-lang/rust-clippy
`cast_possible_truncation`: `x.min(C) as T` is only recognized when `C` is a literal
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Summary
cast_possible_truncation knows that x.min(C) bounds the value, but only when C is a literal. With the same bound written as u32::MAX as u64, u32::MAX.into() or u64::from(u32::MAX) it still fires. The last form is what cast_lossless suggests for u32::MAX as u64, so following the suggestion of one lint keeps this one firing.
Related: #9613.
Lint Name
cast_possible_truncation
Reproducer
I tried this code:
#![warn(clippy::cast_possible_truncation)]
pub fn literal(x: u64) -> u32 {
x.min(0xFFFF_FFFF) as u32
}
pub fn cast(x: u64) -> u32 {
x.min(u32::MAX as u64) as u32
}
pub fn into(x: u64) -> u32 {
x.min(u32::MAX.into()) as u32
}
pub fn from(x: u64) -> u32 {
x.min(u64::from(u32::MAX)) as u32
}
I saw this happen:
warning: casting `u64` to `u32` may truncate the value
--> lib.rs:8:5
|
8 | x.min(u32::MAX as u64) as u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#cast_possible_truncation
note: the lint level is defined here
--> lib.rs:1:9
|
1 | #![warn(clippy::cast_possible_truncation)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: ... or use `try_from` and handle the error accordingly
|
8 - x.min(u32::MAX as u64) as u32
8 + u32::try_from(x.min(u32::MAX as u64))
|
warning: casting `u64` to `u32` may truncate the value
--> lib.rs:12:5
|
12 | x.min(u32::MAX.into()) as u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#cast_possible_truncation
help: ... or use `try_from` and handle the error accordingly
|
12 - x.min(u32::MAX.into()) as u32
12 + u32::try_from(x.min(u32::MAX.into()))
|
warning: casting `u64` to `u32` may truncate the value
--> lib.rs:16:5
|
16 | x.min(u64::from(u32::MAX)) as u32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#cast_possible_truncation
help: ... or use `try_from` and handle the error accordingly
|
16 - x.min(u64::from(u32::MAX)) as u32
16 + u32::try_from(x.min(u64::from(u32::MAX)))
|
I expected to see this happen: No warning in any of the four functions, as in literal: the value is bounded by u32::MAX before the cast.
Version
rustc 1.98.0 (88d9e12ae 2026-08-18)
binary: rustc
commit-hash: 88d9e12ae178fab0fb5cc050a94da85685d449ea
commit-date: 2026-08-18
host: x86_64-pc-windows-msvc
release: 1.98.0
LLVM version: 22.1.8
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
Use the cast_possible_truncation lint as the entry point and reproduce the four functions shown in the issue. Trace how bounds from u32::MAX as u64, .into(), and u64::from are recognized, then verify that all four forms avoid the warning while the existing literal case remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100