Auto merge of #9571 - rust-lang:refactor-lit-ints, r=Jarcho
use `is_integer_literal` more I noticed that we have the `is_integer_literal` function in our `clippy_utils`, yet almost everywhere people still match int literal expressions manually. So I searched for instances to replace and shorten the code a bit. --- changelog: none
This commit is contained in:
commit
d6d5ecd625
@ -3,7 +3,7 @@
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, sugg::Sugg};
|
||||
use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, is_integer_literal, sugg::Sugg};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
declare_clippy_lint! {
|
||||
@ -56,13 +56,9 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
|
||||
&& let Some(then_lit) = int_literal(then)
|
||||
&& let Some(else_lit) = int_literal(else_)
|
||||
{
|
||||
let inverted = if
|
||||
check_int_literal_equals_val(then_lit, 1)
|
||||
&& check_int_literal_equals_val(else_lit, 0) {
|
||||
let inverted = if is_integer_literal(then_lit, 1) && is_integer_literal(else_lit, 0) {
|
||||
false
|
||||
} else if
|
||||
check_int_literal_equals_val(then_lit, 0)
|
||||
&& check_int_literal_equals_val(else_lit, 1) {
|
||||
} else if is_integer_literal(then_lit, 0) && is_integer_literal(else_lit, 1) {
|
||||
true
|
||||
} else {
|
||||
// Expression isn't boolean, exit
|
||||
@ -123,14 +119,3 @@ fn int_literal<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>) -> Option<&'tcx rustc_hi
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn check_int_literal_equals_val<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>, expected_value: u128) -> bool {
|
||||
if let ExprKind::Lit(lit) = &expr.kind
|
||||
&& let LitKind::Int(val, _) = lit.node
|
||||
&& val == expected_value
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{in_constant, meets_msrv, msrvs, SpanlessEq};
|
||||
use clippy_utils::{in_constant, is_integer_literal, meets_msrv, msrvs, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
@ -223,16 +222,7 @@ fn check_function<'a>(candidate: &'a Expr<'a>, check: &'a Expr<'a>) -> Option<Co
|
||||
|
||||
/// Check for `expr >= 0`
|
||||
fn check_lower_bound_zero<'a>(candidate: &'a Expr<'_>, check: &'a Expr<'_>) -> Option<Conversion<'a>> {
|
||||
if_chain! {
|
||||
if let ExprKind::Lit(ref lit) = &check.kind;
|
||||
if let LitKind::Int(0, _) = &lit.node;
|
||||
|
||||
then {
|
||||
Some(Conversion::new_any(candidate))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
is_integer_literal(check, 0).then(|| Conversion::new_any(candidate))
|
||||
}
|
||||
|
||||
/// Check for `expr >= (to_type::MIN as from_type)`
|
||||
|
@ -1,4 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_integer_literal;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use if_chain::if_chain;
|
||||
@ -60,8 +61,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, exp: &Expr<'tcx>) {
|
||||
if pathseg.ident.name.as_str() == "from_str_radix";
|
||||
|
||||
// check if the second argument is a primitive `10`
|
||||
if let ExprKind::Lit(lit) = &radix.kind;
|
||||
if let rustc_ast::ast::LitKind::Int(10, _) = lit.node;
|
||||
if is_integer_literal(radix, 10);
|
||||
|
||||
then {
|
||||
let expr = if let ExprKind::AddrOf(_, _, expr) = &src.kind {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{higher, peel_blocks_with_stmt, SpanlessEq};
|
||||
use clippy_utils::{higher, is_integer_literal, peel_blocks_with_stmt, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
@ -131,17 +131,8 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
fn subtracts_one<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a Expr<'a>> {
|
||||
match peel_blocks_with_stmt(expr).kind {
|
||||
ExprKind::AssignOp(ref op1, target, value) => {
|
||||
if_chain! {
|
||||
if BinOpKind::Sub == op1.node;
|
||||
// Check if literal being subtracted is one
|
||||
if let ExprKind::Lit(ref lit1) = value.kind;
|
||||
if let LitKind::Int(1, _) = lit1.node;
|
||||
then {
|
||||
Some(target)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
(BinOpKind::Sub == op1.node && is_integer_literal(value, 1)).then_some(target)
|
||||
},
|
||||
ExprKind::Assign(target, value, _) => {
|
||||
if_chain! {
|
||||
@ -150,8 +141,7 @@ fn subtracts_one<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a Exp
|
||||
|
||||
if SpanlessEq::new(cx).eq_expr(left1, target);
|
||||
|
||||
if let ExprKind::Lit(ref lit1) = right1.kind;
|
||||
if let LitKind::Int(1, _) = lit1.node;
|
||||
if is_integer_literal(right1, 1);
|
||||
then {
|
||||
Some(target)
|
||||
} else {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::SpanlessEq;
|
||||
use rustc_ast::LitKind;
|
||||
use clippy_utils::{is_integer_literal, SpanlessEq};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
@ -26,8 +25,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
|
||||
&& lhs_path.ident.name == sym::len
|
||||
|
||||
// RHS of subtraction is 1
|
||||
&& let ExprKind::Lit(rhs_lit) = &rhs.kind
|
||||
&& let LitKind::Int(1, ..) = rhs_lit.node
|
||||
&& is_integer_literal(rhs, 1)
|
||||
|
||||
// check that recv == lhs_recv `recv.get(lhs_recv.len() - 1)`
|
||||
&& SpanlessEq::new(cx).eq_expr(recv, lhs_recv)
|
||||
|
@ -1,7 +1,6 @@
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_hir_and_then};
|
||||
use clippy_utils::source::{snippet, snippet_opt};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
@ -15,7 +14,7 @@
|
||||
use rustc_span::source_map::{ExpnKind, Span};
|
||||
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{get_parent_expr, in_constant, iter_input_pats, last_path_segment, SpanlessEq};
|
||||
use clippy_utils::{get_parent_expr, in_constant, is_integer_literal, iter_input_pats, last_path_segment, SpanlessEq};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -314,8 +313,7 @@ fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
|
||||
fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
|
||||
if_chain! {
|
||||
if let TyKind::Ptr(ref mut_ty) = ty.kind;
|
||||
if let ExprKind::Lit(ref lit) = e.kind;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
if is_integer_literal(e, 0);
|
||||
if !in_constant(cx, e.hir_id);
|
||||
then {
|
||||
let (msg, sugg_fn) = match mut_ty.mutbl {
|
||||
|
@ -44,26 +44,20 @@ pub fn new(mut allowed: FxHashSet<String>) -> Self {
|
||||
/// Assuming that `expr` is a literal integer, checks operators (+=, -=, *, /) in a
|
||||
/// non-constant environment that won't overflow.
|
||||
fn has_valid_op(op: &Spanned<hir::BinOpKind>, expr: &hir::Expr<'_>) -> bool {
|
||||
if let hir::BinOpKind::Add | hir::BinOpKind::Sub = op.node
|
||||
&& let hir::ExprKind::Lit(ref lit) = expr.kind
|
||||
&& let ast::LitKind::Int(0, _) = lit.node
|
||||
if let hir::ExprKind::Lit(ref lit) = expr.kind &&
|
||||
let ast::LitKind::Int(value, _) = lit.node
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if let hir::BinOpKind::Div | hir::BinOpKind::Rem = op.node
|
||||
&& let hir::ExprKind::Lit(ref lit) = expr.kind
|
||||
&& !matches!(lit.node, ast::LitKind::Int(0, _))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if let hir::BinOpKind::Mul = op.node
|
||||
&& let hir::ExprKind::Lit(ref lit) = expr.kind
|
||||
&& let ast::LitKind::Int(0 | 1, _) = lit.node
|
||||
{
|
||||
return true;
|
||||
match (&op.node, value) {
|
||||
(hir::BinOpKind::Add | hir::BinOpKind::Sub, 0) |
|
||||
(hir::BinOpKind::Mul, 0 | 1) => true,
|
||||
(hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
|
||||
(hir::BinOpKind::Div | hir::BinOpKind::Rem, _) => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the given `expr` has any of the inner `allowed` elements.
|
||||
fn is_allowed_ty(&self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use clippy_utils::consts::constant_simple;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_integer_literal;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::source_map::Span;
|
||||
@ -50,12 +51,10 @@ pub fn check_binary<'tcx>(
|
||||
hir::BinOpKind::Div | hir::BinOpKind::Rem => match &r.kind {
|
||||
hir::ExprKind::Lit(_lit) => (),
|
||||
hir::ExprKind::Unary(hir::UnOp::Neg, expr) => {
|
||||
if let hir::ExprKind::Lit(lit) = &expr.kind {
|
||||
if let rustc_ast::ast::LitKind::Int(1, _) = lit.node {
|
||||
if is_integer_literal(expr, 1) {
|
||||
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
|
||||
self.expr_id = Some(expr.hir_id);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
|
||||
|
@ -1,9 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{get_enclosing_block, is_expr_path_def_path, path_to_local, path_to_local_id, paths, SpanlessEq};
|
||||
use clippy_utils::{
|
||||
get_enclosing_block, is_expr_path_def_path, is_integer_literal, path_to_local, path_to_local_id, paths, SpanlessEq,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor};
|
||||
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, PatKind, QPath, Stmt, StmtKind};
|
||||
@ -219,8 +220,7 @@ fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) {
|
||||
&& path_to_local_id(self_arg, self.vec_alloc.local_id)
|
||||
&& path.ident.name == sym!(resize)
|
||||
// Check that is filled with 0
|
||||
&& let ExprKind::Lit(ref lit) = fill_arg.kind
|
||||
&& let LitKind::Int(0, _) = lit.node {
|
||||
&& is_integer_literal(fill_arg, 0) {
|
||||
// Check that len expression is equals to `with_capacity` expression
|
||||
if SpanlessEq::new(self.cx).eq_expr(len_arg, self.vec_alloc.len_expr) {
|
||||
self.slow_expression = Some(InitializationType::Resize(expr));
|
||||
@ -255,9 +255,7 @@ fn is_repeat_zero(&self, expr: &Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let ExprKind::Call(fn_expr, [repeat_arg]) = expr.kind;
|
||||
if is_expr_path_def_path(self.cx, fn_expr, &paths::ITER_REPEAT);
|
||||
if let ExprKind::Lit(ref lit) = repeat_arg.kind;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
|
||||
if is_integer_literal(repeat_arg, 0);
|
||||
then {
|
||||
true
|
||||
} else {
|
||||
|
@ -1,8 +1,6 @@
|
||||
use clippy_utils::consts::{constant_context, Constant};
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_path_diagnostic_item;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::LitKind;
|
||||
use clippy_utils::{is_integer_literal, is_path_diagnostic_item};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::Ty;
|
||||
@ -19,38 +17,29 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
|
||||
|
||||
// Catching transmute over constants that resolve to `null`.
|
||||
let mut const_eval_context = constant_context(cx, cx.typeck_results());
|
||||
if_chain! {
|
||||
if let ExprKind::Path(ref _qpath) = arg.kind;
|
||||
if let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg);
|
||||
if x == 0;
|
||||
then {
|
||||
if let ExprKind::Path(ref _qpath) = arg.kind &&
|
||||
let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg) &&
|
||||
x == 0
|
||||
{
|
||||
span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Catching:
|
||||
// `std::mem::transmute(0 as *const i32)`
|
||||
if_chain! {
|
||||
if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
|
||||
if let ExprKind::Lit(ref lit) = inner_expr.kind;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
then {
|
||||
if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind && is_integer_literal(inner_expr, 0) {
|
||||
span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Catching:
|
||||
// `std::mem::transmute(std::ptr::null::<i32>())`
|
||||
if_chain! {
|
||||
if let ExprKind::Call(func1, []) = arg.kind;
|
||||
if is_path_diagnostic_item(cx, func1, sym::ptr_null);
|
||||
then {
|
||||
if let ExprKind::Call(func1, []) = arg.kind &&
|
||||
is_path_diagnostic_item(cx, func1, sym::ptr_null)
|
||||
{
|
||||
span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
// Also catch transmutations of variables which are known nulls.
|
||||
|
@ -1,8 +1,7 @@
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
||||
use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_uninit_value_valid_for_ty};
|
||||
use clippy_utils::{is_lint_allowed, path_to_local_id, peel_hir_expr_while, SpanlessEq};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use clippy_utils::{is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while, SpanlessEq};
|
||||
use rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, PathSegment, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
@ -216,7 +215,7 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
|
||||
let self_type = cx.typeck_results().expr_ty(self_expr).peel_refs();
|
||||
if is_type_diagnostic_item(cx, self_type, sym::Vec)
|
||||
&& path.ident.name.as_str() == "set_len"
|
||||
&& !is_literal_zero(arg)
|
||||
&& !is_integer_literal(arg, 0)
|
||||
{
|
||||
Some((self_expr, expr.span))
|
||||
} else {
|
||||
@ -226,13 +225,3 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_literal_zero(arg: &Expr<'_>) -> bool {
|
||||
if let ExprKind::Lit(lit) = &arg.kind
|
||||
&& let LitKind::Int(0, _) = lit.node
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user