Skip to content

Commit 13824d1

Browse files
committed
Move IntegerDivision into Operators lint pass
1 parent a9a1fe8 commit 13824d1

File tree

6 files changed

+57
-64
lines changed

6 files changed

+57
-64
lines changed

clippy_lints/src/integer_division.rs

Lines changed: 0 additions & 60 deletions
This file was deleted.

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ store.register_lints(&[
190190
init_numbered_fields::INIT_NUMBERED_FIELDS,
191191
inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
192192
int_plus_one::INT_PLUS_ONE,
193-
integer_division::INTEGER_DIVISION,
194193
invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
195194
items_after_statements::ITEMS_AFTER_STATEMENTS,
196195
iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
@@ -422,6 +421,7 @@ store.register_lints(&[
422421
operators::IDENTITY_OP,
423422
operators::INEFFECTIVE_BIT_MASK,
424423
operators::INTEGER_ARITHMETIC,
424+
operators::INTEGER_DIVISION,
425425
operators::MISREFACTORED_ASSIGN_OP,
426426
operators::OP_REF,
427427
operators::VERBOSE_BIT_MASK,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
2424
LintId::of(implicit_return::IMPLICIT_RETURN),
2525
LintId::of(indexing_slicing::INDEXING_SLICING),
2626
LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
27-
LintId::of(integer_division::INTEGER_DIVISION),
2827
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
2928
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
3029
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
@@ -50,6 +49,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
5049
LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
5150
LintId::of(operators::FLOAT_ARITHMETIC),
5251
LintId::of(operators::INTEGER_ARITHMETIC),
52+
LintId::of(operators::INTEGER_DIVISION),
5353
LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
5454
LintId::of(panic_unimplemented::PANIC),
5555
LintId::of(panic_unimplemented::TODO),

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ mod inherent_to_string;
251251
mod init_numbered_fields;
252252
mod inline_fn_without_body;
253253
mod int_plus_one;
254-
mod integer_division;
255254
mod invalid_upcast_comparisons;
256255
mod items_after_statements;
257256
mod iter_not_returning_iterator;
@@ -710,7 +709,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
710709
store.register_late_pass(|| Box::new(assertions_on_constants::AssertionsOnConstants));
711710
store.register_late_pass(|| Box::new(transmuting_null::TransmutingNull));
712711
store.register_late_pass(|| Box::new(path_buf_push_overwrite::PathBufPushOverwrite));
713-
store.register_late_pass(|| Box::new(integer_division::IntegerDivision));
714712
store.register_late_pass(|| Box::new(inherent_to_string::InherentToString));
715713
let max_trait_bounds = conf.max_trait_bounds;
716714
store.register_late_pass(move || Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use rustc_hir as hir;
3+
use rustc_lint::LateContext;
4+
5+
use super::INTEGER_DIVISION;
6+
7+
pub(crate) fn check<'tcx>(
8+
cx: &LateContext<'tcx>,
9+
expr: &'tcx hir::Expr<'_>,
10+
op: hir::BinOpKind,
11+
left: &'tcx hir::Expr<'_>,
12+
right: &'tcx hir::Expr<'_>,
13+
) {
14+
if op == hir::BinOpKind::Div
15+
&& cx.typeck_results().expr_ty(left).is_integral()
16+
&& cx.typeck_results().expr_ty(right).is_integral()
17+
{
18+
span_lint_and_help(
19+
cx,
20+
INTEGER_DIVISION,
21+
expr.span,
22+
"integer division",
23+
None,
24+
"division of integers may cause loss of precision. consider using floats",
25+
);
26+
}
27+
}

clippy_lints/src/operators/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod eq_op;
1212
mod erasing_op;
1313
mod float_equality_without_abs;
1414
mod identity_op;
15+
mod integer_division;
1516
mod misrefactored_assign_op;
1617
mod op_ref;
1718
mod verbose_bit_mask;
@@ -431,6 +432,31 @@ declare_clippy_lint! {
431432
"using identity operations, e.g., `x + 0` or `y / 1`"
432433
}
433434

435+
declare_clippy_lint! {
436+
/// ### What it does
437+
/// Checks for division of integers
438+
///
439+
/// ### Why is this bad?
440+
/// When outside of some very specific algorithms,
441+
/// integer division is very often a mistake because it discards the
442+
/// remainder.
443+
///
444+
/// ### Example
445+
/// ```rust
446+
/// // Bad
447+
/// let x = 3 / 2;
448+
/// println!("{}", x);
449+
///
450+
/// // Good
451+
/// let x = 3f32 / 2f32;
452+
/// println!("{}", x);
453+
/// ```
454+
#[clippy::version = "1.37.0"]
455+
pub INTEGER_DIVISION,
456+
restriction,
457+
"integer division may cause loss of precision"
458+
}
459+
434460
pub struct Operators {
435461
arithmetic_context: arithmetic::Context,
436462
verbose_bit_mask_threshold: u64,
@@ -451,6 +477,7 @@ impl_lint_pass!(Operators => [
451477
ERASING_OP,
452478
FLOAT_EQUALITY_WITHOUT_ABS,
453479
IDENTITY_OP,
480+
INTEGER_DIVISION,
454481
]);
455482
impl Operators {
456483
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
@@ -480,6 +507,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
480507
double_comparison::check(cx, op.node, lhs, rhs, e.span);
481508
duration_subsec::check(cx, e, op.node, lhs, rhs);
482509
float_equality_without_abs::check(cx, e, op.node, lhs, rhs);
510+
integer_division::check(cx, e, op.node, lhs, rhs);
483511
},
484512
ExprKind::AssignOp(op, lhs, rhs) => {
485513
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);

0 commit comments

Comments
 (0)