Move IntegerDivision
into Operators
lint pass
This commit is contained in:
parent
83de67cfec
commit
a8df16ae1d
@ -1,61 +0,0 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for division of integers
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// When outside of some very specific algorithms,
|
||||
/// integer division is very often a mistake because it discards the
|
||||
/// remainder.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = 3 / 2;
|
||||
/// println!("{}", x);
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// let x = 3f32 / 2f32;
|
||||
/// println!("{}", x);
|
||||
/// ```
|
||||
#[clippy::version = "1.37.0"]
|
||||
pub INTEGER_DIVISION,
|
||||
restriction,
|
||||
"integer division may cause loss of precision"
|
||||
}
|
||||
|
||||
declare_lint_pass!(IntegerDivision => [INTEGER_DIVISION]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for IntegerDivision {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
|
||||
if is_integer_division(cx, expr) {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
INTEGER_DIVISION,
|
||||
expr.span,
|
||||
"integer division",
|
||||
None,
|
||||
"division of integers may cause loss of precision. consider using floats",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_integer_division<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Binary(binop, left, right) = &expr.kind;
|
||||
if binop.node == hir::BinOpKind::Div;
|
||||
then {
|
||||
let (left_ty, right_ty) = (cx.typeck_results().expr_ty(left), cx.typeck_results().expr_ty(right));
|
||||
return left_ty.is_integral() && right_ty.is_integral();
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
@ -194,7 +194,6 @@ store.register_lints(&[
|
||||
init_numbered_fields::INIT_NUMBERED_FIELDS,
|
||||
inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
|
||||
int_plus_one::INT_PLUS_ONE,
|
||||
integer_division::INTEGER_DIVISION,
|
||||
invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
|
||||
items_after_statements::ITEMS_AFTER_STATEMENTS,
|
||||
iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
|
||||
@ -434,6 +433,7 @@ store.register_lints(&[
|
||||
operators::IDENTITY_OP,
|
||||
operators::INEFFECTIVE_BIT_MASK,
|
||||
operators::INTEGER_ARITHMETIC,
|
||||
operators::INTEGER_DIVISION,
|
||||
operators::MISREFACTORED_ASSIGN_OP,
|
||||
operators::OP_REF,
|
||||
operators::VERBOSE_BIT_MASK,
|
||||
|
@ -25,7 +25,6 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
|
||||
LintId::of(implicit_return::IMPLICIT_RETURN),
|
||||
LintId::of(indexing_slicing::INDEXING_SLICING),
|
||||
LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
|
||||
LintId::of(integer_division::INTEGER_DIVISION),
|
||||
LintId::of(large_include_file::LARGE_INCLUDE_FILE),
|
||||
LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
|
||||
LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
|
||||
@ -52,6 +51,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
|
||||
LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
|
||||
LintId::of(operators::FLOAT_ARITHMETIC),
|
||||
LintId::of(operators::INTEGER_ARITHMETIC),
|
||||
LintId::of(operators::INTEGER_DIVISION),
|
||||
LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
|
||||
LintId::of(panic_unimplemented::PANIC),
|
||||
LintId::of(panic_unimplemented::TODO),
|
||||
|
@ -254,7 +254,6 @@ mod inherent_to_string;
|
||||
mod init_numbered_fields;
|
||||
mod inline_fn_without_body;
|
||||
mod int_plus_one;
|
||||
mod integer_division;
|
||||
mod invalid_upcast_comparisons;
|
||||
mod items_after_statements;
|
||||
mod iter_not_returning_iterator;
|
||||
@ -734,7 +733,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||
store.register_late_pass(|| Box::new(assertions_on_constants::AssertionsOnConstants));
|
||||
store.register_late_pass(|| Box::new(transmuting_null::TransmutingNull));
|
||||
store.register_late_pass(|| Box::new(path_buf_push_overwrite::PathBufPushOverwrite));
|
||||
store.register_late_pass(|| Box::new(integer_division::IntegerDivision));
|
||||
store.register_late_pass(|| Box::new(inherent_to_string::InherentToString));
|
||||
let max_trait_bounds = conf.max_trait_bounds;
|
||||
store.register_late_pass(move || Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
|
||||
|
27
clippy_lints/src/operators/integer_division.rs
Normal file
27
clippy_lints/src/operators/integer_division.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
|
||||
use super::INTEGER_DIVISION;
|
||||
|
||||
pub(crate) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx hir::Expr<'_>,
|
||||
op: hir::BinOpKind,
|
||||
left: &'tcx hir::Expr<'_>,
|
||||
right: &'tcx hir::Expr<'_>,
|
||||
) {
|
||||
if op == hir::BinOpKind::Div
|
||||
&& cx.typeck_results().expr_ty(left).is_integral()
|
||||
&& cx.typeck_results().expr_ty(right).is_integral()
|
||||
{
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
INTEGER_DIVISION,
|
||||
expr.span,
|
||||
"integer division",
|
||||
None,
|
||||
"division of integers may cause loss of precision. consider using floats",
|
||||
);
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ mod eq_op;
|
||||
mod erasing_op;
|
||||
mod float_equality_without_abs;
|
||||
mod identity_op;
|
||||
mod integer_division;
|
||||
mod misrefactored_assign_op;
|
||||
mod numeric_arithmetic;
|
||||
mod op_ref;
|
||||
@ -437,6 +438,32 @@ declare_clippy_lint! {
|
||||
"using identity operations, e.g., `x + 0` or `y / 1`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for division of integers
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// When outside of some very specific algorithms,
|
||||
/// integer division is very often a mistake because it discards the
|
||||
/// remainder.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust
|
||||
/// let x = 3 / 2;
|
||||
/// println!("{}", x);
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// let x = 3f32 / 2f32;
|
||||
/// println!("{}", x);
|
||||
/// ```
|
||||
#[clippy::version = "1.37.0"]
|
||||
pub INTEGER_DIVISION,
|
||||
restriction,
|
||||
"integer division may cause loss of precision"
|
||||
}
|
||||
|
||||
pub struct Operators {
|
||||
arithmetic_context: numeric_arithmetic::Context,
|
||||
verbose_bit_mask_threshold: u64,
|
||||
@ -457,6 +484,7 @@ impl_lint_pass!(Operators => [
|
||||
ERASING_OP,
|
||||
FLOAT_EQUALITY_WITHOUT_ABS,
|
||||
IDENTITY_OP,
|
||||
INTEGER_DIVISION,
|
||||
]);
|
||||
impl Operators {
|
||||
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
|
||||
@ -486,6 +514,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
|
||||
double_comparison::check(cx, op.node, lhs, rhs, e.span);
|
||||
duration_subsec::check(cx, e, op.node, lhs, rhs);
|
||||
float_equality_without_abs::check(cx, e, op.node, lhs, rhs);
|
||||
integer_division::check(cx, e, op.node, lhs, rhs);
|
||||
},
|
||||
ExprKind::AssignOp(op, lhs, rhs) => {
|
||||
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
|
||||
|
Loading…
x
Reference in New Issue
Block a user