From ef1db3f502e081535ee8144deaf0f7d0aaf08f75 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Fri, 11 Oct 2024 19:11:32 +0100 Subject: [PATCH] Check MethodCall/Call arg count earlier or at all --- clippy_lints/src/box_default.rs | 2 +- .../src/casts/cast_abs_to_unsigned.rs | 2 +- clippy_lints/src/casts/cast_ptr_alignment.rs | 2 +- clippy_lints/src/create_dir.rs | 2 +- clippy_lints/src/default.rs | 4 +-- clippy_lints/src/exit.rs | 2 +- clippy_lints/src/explicit_write.rs | 2 +- clippy_lints/src/floating_point_arithmetic.rs | 4 +-- clippy_lints/src/format_impl.rs | 2 +- clippy_lints/src/if_let_mutex.rs | 2 +- clippy_lints/src/large_futures.rs | 2 +- clippy_lints/src/len_zero.rs | 18 ++--------- .../src/loops/manual_while_let_some.rs | 11 ++++--- clippy_lints/src/loops/same_item_push.rs | 6 ++-- clippy_lints/src/main_recursion.rs | 2 +- clippy_lints/src/manual_bits.rs | 2 +- clippy_lints/src/manual_is_power_of_two.rs | 4 +-- .../src/manual_slice_size_calculation.rs | 4 +-- clippy_lints/src/manual_string_new.rs | 19 +++++------- .../src/matches/redundant_pattern_match.rs | 2 +- clippy_lints/src/matches/try_err.rs | 4 +-- clippy_lints/src/methods/clone_on_copy.rs | 2 +- clippy_lints/src/methods/iter_filter.rs | 4 +-- .../src/methods/manual_c_str_literals.rs | 2 +- .../methods/manual_saturating_arithmetic.rs | 3 +- clippy_lints/src/methods/map_clone.rs | 3 +- clippy_lints/src/methods/needless_collect.rs | 5 ++- clippy_lints/src/methods/or_fun_call.rs | 2 +- .../src/methods/read_line_without_trim.rs | 3 +- .../src/methods/readonly_write_lock.rs | 2 +- clippy_lints/src/methods/seek_from_current.rs | 5 ++- .../seek_to_start_instead_of_rewind.rs | 5 ++- .../src/methods/single_char_insert_string.rs | 2 +- .../src/methods/single_char_push_string.rs | 2 +- clippy_lints/src/methods/str_splitn.rs | 2 +- .../src/methods/uninit_assumed_init.rs | 3 +- clippy_lints/src/methods/useless_asref.rs | 5 ++- .../src/missing_asserts_for_indexing.rs | 2 +- clippy_lints/src/mut_reference.rs | 6 ++-- clippy_lints/src/non_canonical_impls.rs | 2 +- clippy_lints/src/non_zero_suggestions.rs | 2 +- clippy_lints/src/operators/float_cmp.rs | 2 +- clippy_lints/src/ptr_offset_with_cast.rs | 2 +- clippy_lints/src/question_mark.rs | 7 ++--- clippy_lints/src/returns.rs | 2 +- .../src/significant_drop_tightening.rs | 3 +- clippy_lints/src/size_of_in_element_count.rs | 2 +- .../src/slow_vector_initialization.rs | 4 +-- clippy_lints/src/strings.rs | 11 +++---- clippy_lints/src/to_digit_is_some.rs | 5 ++- clippy_lints/src/unit_types/unit_arg.rs | 9 +++--- .../src/unnecessary_map_on_constructor.rs | 10 ++---- .../src/unnecessary_owned_empty_strings.rs | 4 +-- clippy_lints/src/unused_io_amount.rs | 4 +-- clippy_lints/src/unwrap.rs | 9 +++--- clippy_lints/src/useless_conversion.rs | 4 +-- .../utils/internal_lints/collapsible_calls.rs | 31 ++++++++++++------- clippy_lints/src/vec.rs | 2 +- clippy_utils/src/consts.rs | 5 ++- 59 files changed, 127 insertions(+), 149 deletions(-) diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs index 40d154c0bdf..bf1d077fec2 100644 --- a/clippy_lints/src/box_default.rs +++ b/clippy_lints/src/box_default.rs @@ -47,7 +47,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // And the call is that of a `Box` method && path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box()) // And the single argument to the call is another function call - // This is the `T::default()` of `Box::new(T::default())` + // This is the `T::default()` (or default equivalent) of `Box::new(T::default())` && let ExprKind::Call(arg_path, _) = arg.kind // And we are not in a foreign crate's macro && !in_external_macro(cx.sess(), expr.span) diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs index d4d5ee37bcc..b7b63250864 100644 --- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs +++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs @@ -19,7 +19,7 @@ pub(super) fn check( if msrv.meets(msrvs::UNSIGNED_ABS) && let ty::Int(from) = cast_from.kind() && let ty::Uint(to) = cast_to.kind() - && let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind + && let ExprKind::MethodCall(method_path, receiver, [], _) = cast_expr.kind && method_path.ident.name.as_str() == "abs" { let span = if from.bit_width() == to.bit_width() { diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs index 960c81045e3..b11b967f8bc 100644 --- a/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) { cx.typeck_results().expr_ty(expr), ); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); - } else if let ExprKind::MethodCall(method_path, self_arg, ..) = &expr.kind { + } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind { if method_path.ident.name == sym!(cast) && let Some(generic_args) = method_path.args && let [GenericArg::Type(cast_to)] = generic_args.args diff --git a/clippy_lints/src/create_dir.rs b/clippy_lints/src/create_dir.rs index 24570d8f440..b43906903a0 100644 --- a/clippy_lints/src/create_dir.rs +++ b/clippy_lints/src/create_dir.rs @@ -34,7 +34,7 @@ impl LateLintPass<'_> for CreateDir { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if let ExprKind::Call(func, [arg, ..]) = expr.kind + if let ExprKind::Call(func, [arg]) = expr.kind && let ExprKind::Path(ref path) = func.kind && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id) diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs index dc10b64698b..de775b64795 100644 --- a/clippy_lints/src/default.rs +++ b/clippy_lints/src/default.rs @@ -83,7 +83,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !expr.span.from_expansion() // Avoid cases already linted by `field_reassign_with_default` && !self.reassigned_linted.contains(&expr.span) - && let ExprKind::Call(path, ..) = expr.kind + && let ExprKind::Call(path, []) = expr.kind && !in_automatically_derived(cx.tcx, expr.hir_id) && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() @@ -253,7 +253,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) { /// Checks if the given expression is the `default` method belonging to the `Default` trait. fn is_expr_default<'tcx>(expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> bool { - if let ExprKind::Call(fn_expr, _) = &expr.kind + if let ExprKind::Call(fn_expr, []) = &expr.kind && let ExprKind::Path(qpath) = &fn_expr.kind && let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id) { diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index f37d11f7eb9..3c235fab009 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { - if let ExprKind::Call(path_expr, _args) = e.kind + if let ExprKind::Call(path_expr, [_]) = e.kind && let ExprKind::Path(ref path) = path_expr.kind && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::process_exit, def_id) diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index 5b423a96918..4e4434ec7d1 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -57,7 +57,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { && unwrap_fun.ident.name == sym::unwrap // match call to write_fmt && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind) - && let ExprKind::Call(write_recv_path, _) = write_recv.kind + && let ExprKind::Call(write_recv_path, []) = write_recv.kind && write_fun.ident.name == sym!(write_fmt) && let Some(def_id) = path_def_id(cx, write_recv_path) { diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 8da6623f34d..daa199779e3 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -436,12 +436,12 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) { lhs, rhs, ) = expr.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = &lhs.kind + && path.ident.name.as_str() == "exp" && cx.typeck_results().expr_ty(lhs).is_floating_point() && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs) && (F32(1.0) == value || F64(1.0) == value) - && let ExprKind::MethodCall(path, self_arg, ..) = &lhs.kind && cx.typeck_results().expr_ty(self_arg).is_floating_point() - && path.ident.name.as_str() == "exp" { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs index 7c0515b8c56..5619cb0ab1b 100644 --- a/clippy_lints/src/format_impl.rs +++ b/clippy_lints/src/format_impl.rs @@ -151,7 +151,7 @@ struct FormatImplExpr<'a, 'tcx> { impl FormatImplExpr<'_, '_> { fn check_to_string_in_display(&self) { if self.format_trait_impl.name == sym::Display - && let ExprKind::MethodCall(path, self_arg, ..) = self.expr.kind + && let ExprKind::MethodCall(path, self_arg, [], _) = self.expr.kind // Get the hir_id of the object we are calling the method on // Is the method to_string() ? && path.ident.name == sym::to_string diff --git a/clippy_lints/src/if_let_mutex.rs b/clippy_lints/src/if_let_mutex.rs index 1c52514a330..ba80c099a01 100644 --- a/clippy_lints/src/if_let_mutex.rs +++ b/clippy_lints/src/if_let_mutex.rs @@ -82,7 +82,7 @@ fn mutex_lock_call<'tcx>( expr: &'tcx Expr<'_>, op_mutex: Option<&'tcx Expr<'_>>, ) -> ControlFlow<&'tcx Expr<'tcx>> { - if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind + if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind && path.ident.as_str() == "lock" && let ty = cx.typeck_results().expr_ty(self_arg).peel_refs() && is_type_diagnostic_item(cx, ty, sym::Mutex) diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 6f5065e4936..25f9be8b2d7 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -57,7 +57,7 @@ pub fn new(conf: &'static Conf) -> Self { impl<'tcx> LateLintPass<'tcx> for LargeFuture { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if let ExprKind::Match(scrutinee, _, MatchSource::AwaitDesugar) = expr.kind - && let ExprKind::Call(func, [arg, ..]) = scrutinee.kind + && let ExprKind::Call(func, [arg]) = scrutinee.kind && let ExprKind::Path(QPath::LangItem(LangItem::IntoFutureIntoFuture, ..)) = func.kind && !expr.span.from_expansion() && let ty = cx.typeck_results().expr_ty(arg) diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index c88eb703843..3ca828cb7c2 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -517,7 +517,7 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_> return; } - if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) { + if let (&ExprKind::MethodCall(method_path, receiver, [], _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) { // check if we are in an is_empty() method if let Some(name) = get_item_name(cx, method) { if name.as_str() == "is_empty" { @@ -525,29 +525,17 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_> } } - check_len( - cx, - span, - method_path.ident.name, - receiver, - args, - &lit.node, - op, - compare_to, - ); + check_len(cx, span, method_path.ident.name, receiver, &lit.node, op, compare_to); } else { check_empty_expr(cx, span, method, lit, op); } } -// FIXME(flip1995): Figure out how to reduce the number of arguments -#[allow(clippy::too_many_arguments)] fn check_len( cx: &LateContext<'_>, span: Span, method_name: Symbol, receiver: &Expr<'_>, - args: &[Expr<'_>], lit: &LitKind, op: &str, compare_to: u32, @@ -558,7 +546,7 @@ fn check_len( return; } - if method_name == sym::len && args.is_empty() && has_is_empty(cx, receiver) { + if method_name == sym::len && has_is_empty(cx, receiver) { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, diff --git a/clippy_lints/src/loops/manual_while_let_some.rs b/clippy_lints/src/loops/manual_while_let_some.rs index 7476a87267f..4473a3343c7 100644 --- a/clippy_lints/src/loops/manual_while_let_some.rs +++ b/clippy_lints/src/loops/manual_while_let_some.rs @@ -47,8 +47,9 @@ fn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>, ); } -fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> bool { - if let ExprKind::MethodCall(..) = expr.kind +fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> bool { + if let ExprKind::MethodCall(_, _, args, _) = expr.kind + && args.len() == ARGS_COUNT && let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { cx.tcx.is_diagnostic_item(method, id) @@ -58,9 +59,9 @@ fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> b } fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool { - if (match_method_call(cx, expr, sym::option_unwrap) || match_method_call(cx, expr, sym::option_expect)) + if (match_method_call::<0>(cx, expr, sym::option_unwrap) || match_method_call::<1>(cx, expr, sym::option_expect)) && let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind - && match_method_call(cx, unwrap_recv, sym::vec_pop) + && match_method_call::<0>(cx, unwrap_recv, sym::vec_pop) && let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind { // make sure they're the same `Vec` @@ -96,7 +97,7 @@ fn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &E pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) { if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind && let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind - && match_method_call(cx, cond, sym::vec_is_empty) + && match_method_call::<0>(cx, cond, sym::vec_is_empty) && let ExprKind::Block(body, _) = body.kind && let Some(stmt) = body.stmts.first() { diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index f8659897ffe..d255fea3af2 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -172,10 +172,8 @@ fn get_vec_push<'tcx>( stmt: &'tcx Stmt<'_>, ) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, SyntaxContext)> { if let StmtKind::Semi(semi_stmt) = &stmt.kind - // Extract method being called - && let ExprKind::MethodCall(path, self_expr, args, _) = &semi_stmt.kind - // Figure out the parameters for the method call - && let Some(pushed_item) = args.first() + // Extract method being called and figure out the parameters for the method call + && let ExprKind::MethodCall(path, self_expr, [pushed_item], _) = &semi_stmt.kind // Check that the method being called is push() on a Vec && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec) && path.ident.name.as_str() == "push" diff --git a/clippy_lints/src/main_recursion.rs b/clippy_lints/src/main_recursion.rs index 72807b4b284..01ea2f5debe 100644 --- a/clippy_lints/src/main_recursion.rs +++ b/clippy_lints/src/main_recursion.rs @@ -42,7 +42,7 @@ fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { return; } - if let ExprKind::Call(func, _) = &expr.kind + if let ExprKind::Call(func, []) = &expr.kind && let ExprKind::Path(QPath::Resolved(_, path)) = &func.kind && let Some(def_id) = path.res.opt_def_id() && is_entrypoint_fn(cx, def_id) diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index c0e87e8a1fa..1bd8813e348 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -95,7 +95,7 @@ fn get_one_size_of_ty<'tcx>( } fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(&'tcx rustc_hir::Ty<'tcx>, Ty<'tcx>)> { - if let ExprKind::Call(count_func, _func_args) = expr.kind + if let ExprKind::Call(count_func, []) = expr.kind && let ExprKind::Path(ref count_func_qpath) = count_func.kind && let QPath::Resolved(_, count_func_path) = count_func_qpath && let Some(segment_zero) = count_func_path.segments.first() diff --git a/clippy_lints/src/manual_is_power_of_two.rs b/clippy_lints/src/manual_is_power_of_two.rs index da2a982ee17..b95bcafc12a 100644 --- a/clippy_lints/src/manual_is_power_of_two.rs +++ b/clippy_lints/src/manual_is_power_of_two.rs @@ -41,7 +41,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { && bin_op.node == BinOpKind::Eq { // a.count_ones() == 1 - if let ExprKind::MethodCall(method_name, reciever, _, _) = left.kind + if let ExprKind::MethodCall(method_name, reciever, [], _) = left.kind && method_name.ident.as_str() == "count_ones" && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind() && check_lit(right, 1) @@ -50,7 +50,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { } // 1 == a.count_ones() - if let ExprKind::MethodCall(method_name, reciever, _, _) = right.kind + if let ExprKind::MethodCall(method_name, reciever, [], _) = right.kind && method_name.ident.as_str() == "count_ones" && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind() && check_lit(left, 1) diff --git a/clippy_lints/src/manual_slice_size_calculation.rs b/clippy_lints/src/manual_slice_size_calculation.rs index b24a0f4695a..b97919539a2 100644 --- a/clippy_lints/src/manual_slice_size_calculation.rs +++ b/clippy_lints/src/manual_slice_size_calculation.rs @@ -83,12 +83,12 @@ fn simplify_half<'tcx>( ) -> Option<&'tcx Expr<'tcx>> { if !expr1.span.from_expansion() // expr1 is `[T1].len()`? - && let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind + && let ExprKind::MethodCall(method_path, receiver, [], _) = expr1.kind && method_path.ident.name == sym::len && let receiver_ty = cx.typeck_results().expr_ty(receiver) && let ty::Slice(ty1) = receiver_ty.peel_refs().kind() // expr2 is `size_of::()`? - && let ExprKind::Call(func, _) = expr2.kind + && let ExprKind::Call(func, []) = expr2.kind && let ExprKind::Path(ref func_qpath) = func.kind && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id) diff --git a/clippy_lints/src/manual_string_new.rs b/clippy_lints/src/manual_string_new.rs index 198f7aaddc7..5c2a711b5cb 100644 --- a/clippy_lints/src/manual_string_new.rs +++ b/clippy_lints/src/manual_string_new.rs @@ -52,8 +52,8 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { } match expr.kind { - ExprKind::Call(func, args) => { - parse_call(cx, expr.span, func, args); + ExprKind::Call(func, [arg]) => { + parse_call(cx, expr.span, func, arg); }, ExprKind::MethodCall(path_segment, receiver, ..) => { parse_method_call(cx, expr.span, path_segment, receiver); @@ -93,20 +93,15 @@ fn parse_method_call(cx: &LateContext<'_>, span: Span, path_segment: &PathSegmen let method_arg_kind = &receiver.kind; if ["to_string", "to_owned", "into"].contains(&ident) && is_expr_kind_empty_str(method_arg_kind) { warn_then_suggest(cx, span); - } else if let ExprKind::Call(func, args) = method_arg_kind { + } else if let ExprKind::Call(func, [arg]) = method_arg_kind { // If our first argument is a function call itself, it could be an `unwrap`-like function. // E.g. String::try_from("hello").unwrap(), TryFrom::try_from("").expect("hello"), etc. - parse_call(cx, span, func, args); + parse_call(cx, span, func, arg); } } /// Tries to parse an expression as a function call, emitting the warning if necessary. -fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, args: &[Expr<'_>]) { - if args.len() != 1 { - return; - } - - let arg_kind = &args[0].kind; +fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, arg: &Expr<'_>) { if let ExprKind::Path(qpath) = &func.kind { // String::from(...) or String::try_from(...) if let QPath::TypeRelative(ty, path_seg) = qpath @@ -115,13 +110,13 @@ fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, args: &[Expr<'_ && let QPath::Resolved(_, path) = qpath && let [path_seg] = path.segments && path_seg.ident.name == sym::String - && is_expr_kind_empty_str(arg_kind) + && is_expr_kind_empty_str(&arg.kind) { warn_then_suggest(cx, span); } else if let QPath::Resolved(_, path) = qpath { // From::from(...) or TryFrom::try_from(...) if let [path_seg1, path_seg2] = path.segments - && is_expr_kind_empty_str(arg_kind) + && is_expr_kind_empty_str(&arg.kind) && ((path_seg1.ident.name == sym::From && path_seg2.ident.name == sym::from) || (path_seg1.ident.name == sym::TryFrom && path_seg2.ident.name == sym::try_from)) { diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index b646e87a439..9ca75fb2615 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -210,7 +210,7 @@ fn find_method_sugg_for_if_let<'tcx>( // check that `while_let_on_iterator` lint does not trigger if keyword == "while" - && let ExprKind::MethodCall(method_path, ..) = let_expr.kind + && let ExprKind::MethodCall(method_path, _, [], _) = let_expr.kind && method_path.ident.name == sym::next && is_trait_method(cx, let_expr, sym::Iterator) { diff --git a/clippy_lints/src/matches/try_err.rs b/clippy_lints/src/matches/try_err.rs index b7ffa8b8a78..c7e1b70d19e 100644 --- a/clippy_lints/src/matches/try_err.rs +++ b/clippy_lints/src/matches/try_err.rs @@ -21,10 +21,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine // #[allow(unreachable_code)] // val, // }; - if let ExprKind::Call(match_fun, [try_arg, ..]) = scrutinee.kind + if let ExprKind::Call(match_fun, [try_arg]) = scrutinee.kind && let ExprKind::Path(ref match_fun_path) = match_fun.kind && matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, ..)) - && let ExprKind::Call(err_fun, [err_arg, ..]) = try_arg.kind + && let ExprKind::Call(err_fun, [err_arg]) = try_arg.kind && is_res_lang_ctor(cx, path_res(cx, err_fun), ResultErr) && let Some(return_ty) = find_return_type(cx, &expr.kind) { diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs index 79a473e0e6f..c9604c7b2e2 100644 --- a/clippy_lints/src/methods/clone_on_copy.rs +++ b/clippy_lints/src/methods/clone_on_copy.rs @@ -58,7 +58,7 @@ pub(super) fn check( return; }, // ? is a Call, makes sure not to rec *x?, but rather (*x)? - ExprKind::Call(hir_callee, _) => matches!( + ExprKind::Call(hir_callee, [_]) => matches!( hir_callee.kind, ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, ..)) ), diff --git a/clippy_lints/src/methods/iter_filter.rs b/clippy_lints/src/methods/iter_filter.rs index f6612c984a7..30387ba62a7 100644 --- a/clippy_lints/src/methods/iter_filter.rs +++ b/clippy_lints/src/methods/iter_filter.rs @@ -106,9 +106,9 @@ fn pat_is_recv(ident: Ident, param: &hir::Pat<'_>) -> bool { fn parent_is_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { if let Some(expr) = get_parent_expr(cx, expr) - && is_trait_method(cx, expr, sym::Iterator) - && let ExprKind::MethodCall(path, _, _, _) = expr.kind + && let ExprKind::MethodCall(path, _, [_], _) = expr.kind && path.ident.name == sym::map + && is_trait_method(cx, expr, sym::Iterator) { return true; } diff --git a/clippy_lints/src/methods/manual_c_str_literals.rs b/clippy_lints/src/methods/manual_c_str_literals.rs index 96af9db1af7..d33cdaca2e4 100644 --- a/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/clippy_lints/src/methods/manual_c_str_literals.rs @@ -84,7 +84,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args /// Checks `CStr::from_ptr(b"foo\0".as_ptr().cast())` fn check_from_ptr(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) { - if let ExprKind::MethodCall(method, lit, ..) = peel_ptr_cast(arg).kind + if let ExprKind::MethodCall(method, lit, [], _) = peel_ptr_cast(arg).kind && method.ident.name == sym::as_ptr && !lit.span.from_expansion() && let ExprKind::Lit(lit) = lit.kind diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs index 9e3b313156e..13918ed11b8 100644 --- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs +++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs @@ -68,8 +68,7 @@ enum MinMax { fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { // `T::max_value()` `T::min_value()` inherent methods - if let hir::ExprKind::Call(func, args) = &expr.kind - && args.is_empty() + if let hir::ExprKind::Call(func, []) = &expr.kind && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = &func.kind { match segment.ident.as_str() { diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index ac378ff3702..515d4a11ed5 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -86,9 +86,8 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ } } }, - hir::ExprKind::Call(call, args) => { + hir::ExprKind::Call(call, [arg]) => { if let hir::ExprKind::Path(qpath) = call.kind - && let [arg] = args && ident_eq(name, arg) { handle_path(cx, call, &qpath, e, recv); diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index c58e27e37ad..96a31812ca4 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -321,7 +321,10 @@ fn visit_block(&mut self, block: &'tcx Block<'tcx>) { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { // Check function calls on our collection if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind { - if method_name.ident.name == sym!(collect) && is_trait_method(self.cx, expr, sym::Iterator) { + if args.is_empty() + && method_name.ident.name == sym!(collect) + && is_trait_method(self.cx, expr, sym::Iterator) + { self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv)); self.visit_expr(recv); return; diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index b971f60d416..410e5aa41b0 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -259,7 +259,7 @@ fn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) if body.params.is_empty() && let hir::Expr { kind, .. } = &body.value - && let hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, self_arg, _, _) = kind + && let hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, self_arg, [], _) = kind && ident.name == sym::to_string && let hir::Expr { kind, .. } = self_arg && let hir::ExprKind::Lit(lit) = kind diff --git a/clippy_lints/src/methods/read_line_without_trim.rs b/clippy_lints/src/methods/read_line_without_trim.rs index 0c8b6284284..65e545ed03a 100644 --- a/clippy_lints/src/methods/read_line_without_trim.rs +++ b/clippy_lints/src/methods/read_line_without_trim.rs @@ -43,7 +43,8 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { if let Some(parent) = get_parent_expr(cx, expr) { let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind { - if segment.ident.name == sym!(parse) + if args.is_empty() + && segment.ident.name == sym!(parse) && let parse_result_ty = cx.typeck_results().expr_ty(parent) && is_type_diagnostic_item(cx, parse_result_ty, sym::Result) && let ty::Adt(_, substs) = parse_result_ty.kind() diff --git a/clippy_lints/src/methods/readonly_write_lock.rs b/clippy_lints/src/methods/readonly_write_lock.rs index 774aaec1afd..40b6becd453 100644 --- a/clippy_lints/src/methods/readonly_write_lock.rs +++ b/clippy_lints/src/methods/readonly_write_lock.rs @@ -10,7 +10,7 @@ use rustc_span::sym; fn is_unwrap_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - if let ExprKind::MethodCall(path, receiver, ..) = expr.kind + if let ExprKind::MethodCall(path, receiver, [], _) = expr.kind && path.ident.name == sym::unwrap { is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver).peel_refs(), sym::Result) diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs index 7ef07fe899c..d318462e584 100644 --- a/clippy_lints/src/methods/seek_from_current.rs +++ b/clippy_lints/src/methods/seek_from_current.rs @@ -34,14 +34,13 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &' } fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool { - if let ExprKind::Call(f, args) = expr.kind + if let ExprKind::Call(f, [arg]) = expr.kind && let ExprKind::Path(ref path) = f.kind && let Some(ctor_call_id) = cx.qpath_res(path, f.hir_id).opt_def_id() && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Current), ctor_call_id) { // check if argument of `SeekFrom::Current` is `0` - if args.len() == 1 - && let ExprKind::Lit(lit) = args[0].kind + if let ExprKind::Lit(lit) = arg.kind && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node { return true; diff --git a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs index 9c966f010f1..7b1dd9e58c5 100644 --- a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs +++ b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs @@ -26,12 +26,11 @@ pub(super) fn check<'tcx>( if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek) && implements_trait(cx, ty, seek_trait_id, &[]) - && let ExprKind::Call(func, args1) = arg.kind + && let ExprKind::Call(func, [arg]) = arg.kind && let ExprKind::Path(ref path) = func.kind && let Some(ctor_call_id) = cx.qpath_res(path, func.hir_id).opt_def_id() && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Start), ctor_call_id) - && args1.len() == 1 - && let ExprKind::Lit(lit) = args1[0].kind + && let ExprKind::Lit(lit) = arg.kind && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node { let method_call_span = expr.span.with_lo(name_span.lo()); diff --git a/clippy_lints/src/methods/single_char_insert_string.rs b/clippy_lints/src/methods/single_char_insert_string.rs index e2f76ac114c..4a1d25deade 100644 --- a/clippy_lints/src/methods/single_char_insert_string.rs +++ b/clippy_lints/src/methods/single_char_insert_string.rs @@ -27,7 +27,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir:: } if let ExprKind::AddrOf(BorrowKind::Ref, _, arg) = &args[1].kind - && let ExprKind::MethodCall(path_segment, method_arg, _, _) = &arg.kind + && let ExprKind::MethodCall(path_segment, method_arg, [], _) = &arg.kind && path_segment.ident.name == rustc_span::sym::to_string && (is_ref_char(cx, method_arg) || is_char(cx, method_arg)) { diff --git a/clippy_lints/src/methods/single_char_push_string.rs b/clippy_lints/src/methods/single_char_push_string.rs index 4ae8634305d..bc271d59392 100644 --- a/clippy_lints/src/methods/single_char_push_string.rs +++ b/clippy_lints/src/methods/single_char_push_string.rs @@ -26,7 +26,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir:: } if let ExprKind::AddrOf(BorrowKind::Ref, _, arg) = &args[0].kind - && let ExprKind::MethodCall(path_segment, method_arg, _, _) = &arg.kind + && let ExprKind::MethodCall(path_segment, method_arg, [], _) = &arg.kind && path_segment.ident.name == rustc_span::sym::to_string && (is_ref_char(cx, method_arg) || is_char(cx, method_arg)) { diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index 69032776b2b..a2a7de905ca 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -333,7 +333,7 @@ fn parse_iter_usage<'tcx>( kind: ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)), .. }, - _, + [_], ) => { let parent_span = e.span.parent_callsite().unwrap(); if parent_span.ctxt() == ctxt { diff --git a/clippy_lints/src/methods/uninit_assumed_init.rs b/clippy_lints/src/methods/uninit_assumed_init.rs index 1ee655d61e1..6371fe64428 100644 --- a/clippy_lints/src/methods/uninit_assumed_init.rs +++ b/clippy_lints/src/methods/uninit_assumed_init.rs @@ -9,8 +9,7 @@ /// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter) pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { - if let hir::ExprKind::Call(callee, args) = recv.kind - && args.is_empty() + if let hir::ExprKind::Call(callee, []) = recv.kind && is_path_diagnostic_item(cx, callee, sym::maybe_uninit_uninit) && !is_uninit_value_valid_for_ty(cx, cx.typeck_results().expr_ty_adjusted(expr)) { diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index eafe7486bb0..c309e778116 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -86,12 +86,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, // changing the type, then we can move forward. && rcv_ty.peel_refs() == res_ty.peel_refs() && let Some(parent) = get_parent_expr(cx, expr) - && let hir::ExprKind::MethodCall(segment, _, args, _) = parent.kind + // Check that it only has one argument. + && let hir::ExprKind::MethodCall(segment, _, [arg], _) = parent.kind && segment.ident.span != expr.span // We check that the called method name is `map`. && segment.ident.name == sym::map - // And that it only has one argument. - && let [arg] = args && is_calling_clone(cx, arg) // And that we are not recommending recv.clone() over Arc::clone() or similar && !should_call_clone_as_function(cx, rcv_ty) diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index b40d7eba15e..211aa412b5d 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -139,7 +139,7 @@ fn assert_len_expr<'hir>( && let ExprKind::Binary(bin_op, left, right) = &condition.kind && let Some((cmp, asserted_len, slice_len)) = len_comparison(*bin_op, left, right) - && let ExprKind::MethodCall(method, recv, ..) = &slice_len.kind + && let ExprKind::MethodCall(method, recv, [], _) = &slice_len.kind && cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice() && method.ident.name == sym::len diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs index 3c0f06f66d1..c382fb8fce1 100644 --- a/clippy_lints/src/mut_reference.rs +++ b/clippy_lints/src/mut_reference.rs @@ -47,7 +47,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { if let ExprKind::Path(ref path) = fn_expr.kind { check_arguments( cx, - arguments.iter().collect(), + &mut arguments.iter(), cx.typeck_results().expr_ty(fn_expr), &rustc_hir_pretty::qpath_to_string(&cx.tcx, path), "function", @@ -60,7 +60,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); check_arguments( cx, - iter::once(receiver).chain(arguments.iter()).collect(), + &mut iter::once(receiver).chain(arguments.iter()), method_type, path.ident.as_str(), "method", @@ -73,7 +73,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { fn check_arguments<'tcx>( cx: &LateContext<'tcx>, - arguments: Vec<&Expr<'_>>, + arguments: &mut dyn Iterator>, type_definition: Ty<'tcx>, name: &str, fn_kind: &str, diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index de6a1a36f3e..94855c46567 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -281,7 +281,7 @@ fn self_cmp_call<'tcx>( needs_fully_qualified: &mut bool, ) -> bool { match cmp_expr.kind { - ExprKind::Call(path, [_self, _other]) => path_res(cx, path) + ExprKind::Call(path, [_, _]) => path_res(cx, path) .opt_def_id() .is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id)), ExprKind::MethodCall(_, _, [_other], ..) => { diff --git a/clippy_lints/src/non_zero_suggestions.rs b/clippy_lints/src/non_zero_suggestions.rs index 90a9f2e994b..aefb665b52e 100644 --- a/clippy_lints/src/non_zero_suggestions.rs +++ b/clippy_lints/src/non_zero_suggestions.rs @@ -71,7 +71,7 @@ fn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicabilit if let ExprKind::Call(func, [arg]) = expr.kind && let ExprKind::Path(qpath) = &func.kind && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() - && let ExprKind::MethodCall(rcv_path, receiver, _, _) = &arg.kind + && let ExprKind::MethodCall(rcv_path, receiver, [], _) = &arg.kind && rcv_path.ident.name.as_str() == "get" { let fn_name = cx.tcx.item_name(def_id); diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index df6e6745596..8e394944c21 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -106,7 +106,7 @@ fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { return is_signum(cx, child_expr); } - if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind + if let ExprKind::MethodCall(method_name, self_arg, [], _) = expr.kind && sym!(signum) == method_name.ident.name // Check that the receiver of the signum() is a float (expressions[0] is the receiver of // the method call) diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs index 87a52cb2186..56d07aeae17 100644 --- a/clippy_lints/src/ptr_offset_with_cast.rs +++ b/clippy_lints/src/ptr_offset_with_cast.rs @@ -91,7 +91,7 @@ fn expr_as_ptr_offset_call<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, Method)> { - if let ExprKind::MethodCall(path_segment, arg_0, [arg_1, ..], _) = &expr.kind { + if let ExprKind::MethodCall(path_segment, arg_0, [arg_1], _) = &expr.kind { if is_expr_ty_raw_ptr(cx, arg_0) { if path_segment.ident.name == sym::offset { return Some((arg_0, arg_1, Method::Offset)); diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs index aa9a9001afb..9344cb41993 100644 --- a/clippy_lints/src/question_mark.rs +++ b/clippy_lints/src/question_mark.rs @@ -206,12 +206,11 @@ fn expr_return_none_or_err( sym::Result => path_to_local(expr).is_some() && path_to_local(expr) == path_to_local(cond_expr), _ => false, }, - ExprKind::Call(call_expr, args_expr) => { + ExprKind::Call(call_expr, [arg]) => { if smbl == sym::Result && let ExprKind::Path(QPath::Resolved(_, path)) = &call_expr.kind && let Some(segment) = path.segments.first() && let Some(err_sym) = err_sym - && let Some(arg) = args_expr.first() && let ExprKind::Path(QPath::Resolved(_, arg_path)) = &arg.kind && let Some(PathSegment { ident, .. }) = arg_path.segments.first() { @@ -241,7 +240,7 @@ fn expr_return_none_or_err( fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr) && !is_else_clause(cx.tcx, expr) - && let ExprKind::MethodCall(segment, caller, ..) = &cond.kind + && let ExprKind::MethodCall(segment, caller, [], _) = &cond.kind && let caller_ty = cx.typeck_results().expr_ty(caller) && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then) && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block)) @@ -332,7 +331,7 @@ fn inside_try_block(&self) -> bool { fn is_try_block(cx: &LateContext<'_>, bl: &Block<'_>) -> bool { if let Some(expr) = bl.expr - && let ExprKind::Call(callee, _) = expr.kind + && let ExprKind::Call(callee, [_]) = expr.kind { is_path_lang_item(cx, callee, LangItem::TryTraitFromOutput) } else { diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index d393fbbc118..69058eab0c2 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -357,7 +357,7 @@ fn check_final_expr<'tcx>( let replacement = if let Some(inner_expr) = inner { // if desugar of `do yeet`, don't lint - if let ExprKind::Call(path_expr, _) = inner_expr.kind + if let ExprKind::Call(path_expr, [_]) = inner_expr.kind && let ExprKind::Path(QPath::LangItem(LangItem::TryTraitFromYeet, ..)) = path_expr.kind { return; diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index 0eece922143..abd8363456d 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -421,11 +421,10 @@ fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> { } fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: &Ident, lcx: &LateContext<'_>) -> bool { - if let hir::ExprKind::Call(fun, args) = expr.kind + if let hir::ExprKind::Call(fun, [first_arg]) = expr.kind && let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind && let Res::Def(DefKind::Fn, did) = fun_path.res && lcx.tcx.is_diagnostic_item(sym::mem_drop, did) - && let [first_arg, ..] = args { let has_ident = |local_expr: &hir::Expr<'_>| { if let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &local_expr.kind diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs index 7750d8909d3..db1c75fc3de 100644 --- a/clippy_lints/src/size_of_in_element_count.rs +++ b/clippy_lints/src/size_of_in_element_count.rs @@ -34,7 +34,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted: bool) -> Option> { match expr.kind { - ExprKind::Call(count_func, _func_args) => { + ExprKind::Call(count_func, _) => { if !inverted && let ExprKind::Path(ref count_func_qpath) = count_func.kind && let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id() diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index fc799cad67e..ec6e45256d1 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -152,7 +152,7 @@ fn as_vec_initializer<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Opt && is_path_diagnostic_item(cx, func, sym::vec_with_capacity) { Some(InitializedSize::Initialized(len_expr)) - } else if matches!(expr.kind, ExprKind::Call(func, _) if is_path_diagnostic_item(cx, func, sym::vec_new)) { + } else if matches!(expr.kind, ExprKind::Call(func, []) if is_path_diagnostic_item(cx, func, sym::vec_new)) { Some(InitializedSize::Uninitialized) } else { None @@ -268,7 +268,7 @@ fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'tcx>) { /// Returns `true` if give expression is `repeat(0).take(...)` fn is_repeat_take(&mut self, expr: &'tcx Expr<'tcx>) -> bool { - if let ExprKind::MethodCall(take_path, recv, [len_arg, ..], _) = expr.kind + if let ExprKind::MethodCall(take_path, recv, [len_arg], _) = expr.kind && take_path.ident.name == sym!(take) // Check that take is applied to `repeat(0)` && self.is_repeat_zero(recv) diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 1fb82b66ab8..bf49bb60162 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -253,18 +253,17 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { use rustc_ast::LitKind; - if let ExprKind::Call(fun, args) = e.kind + if let ExprKind::Call(fun, [bytes_arg]) = e.kind // Find std::str::converts::from_utf8 && is_path_diagnostic_item(cx, fun, sym::str_from_utf8) // Find string::as_bytes - && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args[0].kind + && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = bytes_arg.kind && let ExprKind::Index(left, right, _) = args.kind && let (method_names, expressions, _) = method_calls(left, 1) - && method_names.len() == 1 + && method_names == [sym!(as_bytes)] && expressions.len() == 1 && expressions[0].1.is_empty() - && method_names[0] == sym!(as_bytes) // Check for slicer && let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), _, _) = right.kind @@ -393,7 +392,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { return; } - if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind + if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind && path.ident.name == sym::to_string && let ty = cx.typeck_results().expr_ty(self_arg) && let ty::Ref(_, ty, ..) = ty.kind() @@ -449,7 +448,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { return; } - if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind + if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind && path.ident.name == sym::to_string && let ty = cx.typeck_results().expr_ty(self_arg) && is_type_lang_item(cx, ty, LangItem::String) diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs index 4f96a566b63..569812d8106 100644 --- a/clippy_lints/src/to_digit_is_some.rs +++ b/clippy_lints/src/to_digit_is_some.rs @@ -51,9 +51,8 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { None } }, - hir::ExprKind::Call(to_digits_call, to_digit_args) => { - if let [char_arg, radix_arg] = *to_digit_args - && let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind + hir::ExprKind::Call(to_digits_call, [char_arg, radix_arg]) => { + if let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind && let to_digits_call_res = cx.qpath_res(to_digits_path, to_digits_call.hir_id) && let Some(to_digits_def_id) = to_digits_call_res.opt_def_id() && match_def_path(cx, to_digits_def_id, &[ diff --git a/clippy_lints/src/unit_types/unit_arg.rs b/clippy_lints/src/unit_types/unit_arg.rs index 41b2ca5d268..e7d26fa238e 100644 --- a/clippy_lints/src/unit_types/unit_arg.rs +++ b/clippy_lints/src/unit_types/unit_arg.rs @@ -25,14 +25,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { return; } - let args: Vec<_> = match expr.kind { - ExprKind::Call(_, args) => args.iter().collect(), - ExprKind::MethodCall(_, receiver, args, _) => std::iter::once(receiver).chain(args.iter()).collect(), + let (reciever, args) = match expr.kind { + ExprKind::Call(_, args) => (None, args), + ExprKind::MethodCall(_, receiver, args, _) => (Some(receiver), args), _ => return, }; - let args_to_recover = args + let args_to_recover = reciever .into_iter() + .chain(args) .filter(|arg| { if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) { !matches!( diff --git a/clippy_lints/src/unnecessary_map_on_constructor.rs b/clippy_lints/src/unnecessary_map_on_constructor.rs index 8f1eb5019f0..d3700d05b01 100644 --- a/clippy_lints/src/unnecessary_map_on_constructor.rs +++ b/clippy_lints/src/unnecessary_map_on_constructor.rs @@ -38,13 +38,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc if expr.span.from_expansion() { return; } - if let hir::ExprKind::MethodCall(path, recv, args, ..) = expr.kind + if let hir::ExprKind::MethodCall(path, recv, [map_arg], ..) = expr.kind && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)) { - let (constructor_path, constructor_item) = if let hir::ExprKind::Call(constructor, constructor_args) = - recv.kind + let (constructor_path, constructor_item) = if let hir::ExprKind::Call(constructor, [arg, ..]) = recv.kind && let hir::ExprKind::Path(constructor_path) = constructor.kind - && let Some(arg) = constructor_args.first() { if constructor.span.from_expansion() || arg.span.from_expansion() { return; @@ -70,9 +68,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc _ => return, } - if let Some(map_arg) = args.first() - && let hir::ExprKind::Path(fun) = map_arg.kind - { + if let hir::ExprKind::Path(fun) = map_arg.kind { if map_arg.span.from_expansion() { return; } diff --git a/clippy_lints/src/unnecessary_owned_empty_strings.rs b/clippy_lints/src/unnecessary_owned_empty_strings.rs index f01cb457af8..7d996775a58 100644 --- a/clippy_lints/src/unnecessary_owned_empty_strings.rs +++ b/clippy_lints/src/unnecessary_owned_empty_strings.rs @@ -52,8 +52,8 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { Applicability::MachineApplicable, ); } else if cx.tcx.is_diagnostic_item(sym::from_fn, fun_def_id) - && let [.., last_arg] = args - && let ExprKind::Lit(spanned) = &last_arg.kind + && let [arg] = args + && let ExprKind::Lit(spanned) = &arg.kind && let LitKind::Str(symbol, _) = spanned.node && symbol.is_empty() && let inner_expr_type = cx.typeck_results().expr_ty(inner_expr) diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index d2a21b11ef4..cf406b817da 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -222,7 +222,7 @@ fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { } fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { - while let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind + while let ExprKind::Call(func, [ref arg_0]) = expr.kind && matches!( func.kind, ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..)) @@ -244,7 +244,7 @@ fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { /// waited on. Otherwise return None. fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> { if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind { - if let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind { + if let ExprKind::Call(func, [ref arg_0]) = expr.kind { if matches!( func.kind, ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..)) diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs index 6fe660b6a47..096b3ff9a2e 100644 --- a/clippy_lints/src/unwrap.rs +++ b/clippy_lints/src/unwrap.rs @@ -153,13 +153,12 @@ fn is_relevant_result_call(cx: &LateContext<'_>, ty: Ty<'_>, method_name: &str) } } else if let ExprKind::Unary(UnOp::Not, expr) = &expr.kind { return collect_unwrap_info(cx, if_expr, expr, branch, !invert, false); - } else if let ExprKind::MethodCall(method_name, receiver, args, _) = &expr.kind + } else if let ExprKind::MethodCall(method_name, receiver, [], _) = &expr.kind && let Some(local_id) = path_to_local(receiver) && let ty = cx.typeck_results().expr_ty(receiver) && let name = method_name.ident.as_str() && (is_relevant_option_call(cx, ty, name) || is_relevant_result_call(cx, ty, name)) { - assert!(args.is_empty()); let unwrappable = match name { "is_some" | "is_ok" => true, "is_err" | "is_none" => false, @@ -208,7 +207,7 @@ struct MutationVisitor<'tcx> { /// expression: that will be where the actual method call is. fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool { if let Node::Expr(mutating_expr) = tcx.parent_hir_node(expr_id) - && let ExprKind::MethodCall(path, ..) = mutating_expr.kind + && let ExprKind::MethodCall(path, _, [], _) = mutating_expr.kind { path.ident.name.as_str() == "as_mut" } else { @@ -275,7 +274,7 @@ enum AsRefKind { /// Checks if the expression is a method call to `as_{ref,mut}` and returns the receiver of it. /// If it isn't, the expression itself is returned. fn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Option) { - if let ExprKind::MethodCall(path, recv, ..) = expr.kind { + if let ExprKind::MethodCall(path, recv, [], _) = expr.kind { if path.ident.name == sym::as_ref { (recv, Some(AsRefKind::AsRef)) } else if path.ident.name.as_str() == "as_mut" { @@ -303,7 +302,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { self.visit_branch(expr, cond, else_inner, true); } } else { - // find `unwrap[_err]()` calls: + // find `unwrap[_err]()` or `expect("...")` calls: if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind && let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg) && let Some(id) = path_to_local(self_arg) diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index 29a7949b343..ec3a693d2ef 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -129,7 +129,7 @@ fn into_iter_bound<'tcx>( /// Extracts the receiver of a `.into_iter()` method call. fn into_iter_call<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>) -> Option<&'hir Expr<'hir>> { - if let ExprKind::MethodCall(name, recv, _, _) = expr.kind + if let ExprKind::MethodCall(name, recv, [], _) = expr.kind && is_trait_method(cx, expr, sym::IntoIterator) && name.ident.name == sym::into_iter { @@ -173,7 +173,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { } }, - ExprKind::MethodCall(name, recv, ..) => { + ExprKind::MethodCall(name, recv, [], _) => { if is_trait_method(cx, e, sym::Into) && name.ident.as_str() == "into" { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(recv); diff --git a/clippy_lints/src/utils/internal_lints/collapsible_calls.rs b/clippy_lints/src/utils/internal_lints/collapsible_calls.rs index d8f101a8614..a3f9abe4f96 100644 --- a/clippy_lints/src/utils/internal_lints/collapsible_calls.rs +++ b/clippy_lints/src/utils/internal_lints/collapsible_calls.rs @@ -5,6 +5,7 @@ use rustc_hir::{Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; +use rustc_span::Span; use std::borrow::{Borrow, Cow}; @@ -76,19 +77,19 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { return; } - if let ExprKind::Call(func, and_then_args) = expr.kind + if let ExprKind::Call(func, [call_cx, call_lint, call_sp, call_msg, call_f]) = expr.kind && is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]) - && and_then_args.len() == 5 - && let ExprKind::Closure(&Closure { body, .. }) = &and_then_args[4].kind + && let ExprKind::Closure(&Closure { body, .. }) = &call_f.kind && let body = cx.tcx.hir().body(body) && let only_expr = peel_blocks_with_stmt(body.value) && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind && let ExprKind::Path(..) = recv.kind { - let and_then_snippets = get_and_then_snippets(cx, and_then_args); + let and_then_snippets = + get_and_then_snippets(cx, call_cx.span, call_lint.span, call_sp.span, call_msg.span); let mut sle = SpanlessEq::new(cx).deny_side_effects(); match ps.ident.as_str() { - "span_suggestion" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => { + "span_suggestion" if sle.eq_expr(call_sp, &span_call_args[0]) => { suggest_suggestion( cx, expr, @@ -96,11 +97,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { &span_suggestion_snippets(cx, span_call_args), ); }, - "span_help" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => { + "span_help" if sle.eq_expr(call_sp, &span_call_args[0]) => { let help_snippet = snippet(cx, span_call_args[1].span, r#""...""#); suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true); }, - "span_note" if sle.eq_expr(&and_then_args[2], &span_call_args[0]) => { + "span_note" if sle.eq_expr(call_sp, &span_call_args[0]) => { let note_snippet = snippet(cx, span_call_args[1].span, r#""...""#); suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true); }, @@ -125,11 +126,17 @@ struct AndThenSnippets<'a> { msg: Cow<'a, str>, } -fn get_and_then_snippets<'a, 'hir>(cx: &LateContext<'_>, and_then_snippets: &'hir [Expr<'hir>]) -> AndThenSnippets<'a> { - let cx_snippet = snippet(cx, and_then_snippets[0].span, "cx"); - let lint_snippet = snippet(cx, and_then_snippets[1].span, ".."); - let span_snippet = snippet(cx, and_then_snippets[2].span, "span"); - let msg_snippet = snippet(cx, and_then_snippets[3].span, r#""...""#); +fn get_and_then_snippets( + cx: &LateContext<'_>, + cx_span: Span, + lint_span: Span, + span_span: Span, + msg_span: Span, +) -> AndThenSnippets<'static> { + let cx_snippet = snippet(cx, cx_span, "cx"); + let lint_snippet = snippet(cx, lint_span, ".."); + let span_snippet = snippet(cx, span_span, "span"); + let msg_snippet = snippet(cx, msg_span, r#""...""#); AndThenSnippets { cx: cx_snippet, diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index ce4f41e854d..bbe45a2eda3 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -244,7 +244,7 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"]; - if let ExprKind::MethodCall(path, ..) = e.kind { + if let ExprKind::MethodCall(path, _, [], _) = e.kind { ALLOWED_METHOD_NAMES.contains(&path.ident.name.as_str()) } else { is_trait_method(cx, e, sym::IntoIterator) diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 510034876e0..a1cfb7be647 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -484,10 +484,9 @@ fn expr(&self, e: &Expr<'_>) -> Option> { }), ExprKind::If(cond, then, ref otherwise) => self.ifthenelse(cond, then, *otherwise), ExprKind::Binary(op, left, right) => self.binop(op, left, right), - ExprKind::Call(callee, args) => { + ExprKind::Call(callee, []) => { // We only handle a few const functions for now. - if args.is_empty() - && let ExprKind::Path(qpath) = &callee.kind + if let ExprKind::Path(qpath) = &callee.kind && let Some(did) = self.typeck.qpath_res(qpath, callee.hir_id).opt_def_id() { match self.tcx.get_diagnostic_name(did) {