Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion clippy_lints/src/non_zero_suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ impl<'tcx> LateLintPass<'tcx> for NonZeroSuggestions {
if let ExprKind::Binary(op, _, rhs) = expr.kind
&& matches!(op.node, BinOpKind::Div | BinOpKind::Rem)
{
check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable);
// `Div<NonZero<T>>` and `Rem<NonZero<T>>` are only implemented for unsigned
// integer types; signed integer types do not have these impls, so suggesting
// `NonZeroI*::from(x)` as the divisor produces code that won't compile.
let rhs_ty = cx.typeck_results().expr_ty(rhs);
if matches!(rhs_ty.kind(), ty::Uint(_)) {
check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable);
}
} else {
// Check if the parent expression is a binary operation
let parent_is_binary = cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| {
Expand Down
8 changes: 7 additions & 1 deletion tests/ui/non_zero_suggestions.fixed
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![warn(clippy::non_zero_suggestions)]
use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
use std::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};

fn main() {
/// Positive test cases (lint should trigger)
Expand Down Expand Up @@ -45,6 +45,12 @@ fn main() {
let k: u64 = 300;
let l = NonZeroU32::new(15).unwrap();
let r9 = k / NonZeroU64::from(l);

// Signed integers in div/rem: must NOT trigger because i64 / NonZeroI64 is not in std
let s: i64 = 10;
let t = NonZeroI32::new(3).unwrap();
let r10 = s / i64::from(t.get());
let r11 = s % i64::from(t.get());
}

// Additional function to test the lint in a different context
Expand Down
8 changes: 7 additions & 1 deletion tests/ui/non_zero_suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![warn(clippy::non_zero_suggestions)]
use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
use std::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};

fn main() {
/// Positive test cases (lint should trigger)
Expand Down Expand Up @@ -45,6 +45,12 @@ fn main() {
let k: u64 = 300;
let l = NonZeroU32::new(15).unwrap();
let r9 = k / NonZeroU64::from(l);

// Signed integers in div/rem: must NOT trigger because i64 / NonZeroI64 is not in std
let s: i64 = 10;
let t = NonZeroI32::new(3).unwrap();
let r10 = s / i64::from(t.get());
let r11 = s % i64::from(t.get());
}

// Additional function to test the lint in a different context
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/non_zero_suggestions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ LL | let x = u64::from(NonZeroU32::new(5).unwrap().get());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())`

error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
--> tests/ui/non_zero_suggestions.rs:52:9
--> tests/ui/non_zero_suggestions.rs:58:9
|
LL | x / u64::from(y.get())
| ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`

error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
--> tests/ui/non_zero_suggestions.rs:62:22
--> tests/ui/non_zero_suggestions.rs:68:22
|
LL | self.value / u64::from(divisor.get())
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)`
Expand Down