Skip to content

Commit 3955dc3

Browse files
committed
separate the receiver from arguments in HIR under /clippy
1 parent 87c6da3 commit 3955dc3

File tree

112 files changed

+663
-563
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+663
-563
lines changed

library/portable-simd/crates/std_float/src/lib.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
#![cfg_attr(feature = "as_crate", no_std)] // We are std!
2-
#![cfg_attr(
3-
feature = "as_crate",
4-
feature(platform_intrinsics),
5-
feature(portable_simd)
6-
)]
2+
#![cfg_attr(feature = "as_crate", feature(platform_intrinsics), feature(portable_simd))]
73
#[cfg(not(feature = "as_crate"))]
84
use core::simd;
95
#[cfg(feature = "as_crate")]

src/tools/clippy/book/src/development/common_tools_writing_lints.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Starting with an `expr`, you can check whether it is calling a specific method
6666
impl<'tcx> LateLintPass<'tcx> for MyStructLint {
6767
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
6868
// Check our expr is calling a method
69-
if let hir::ExprKind::MethodCall(path, _, [_self_arg, ..]) = &expr.kind
69+
if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind
7070
// Check the name of this method is `some_method`
7171
&& path.ident.name == sym!(some_method)
7272
// Optionally, check the type of the self argument.

src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
4343
&& matches!(cx.tcx.get_diagnostic_name(macro_call.def_id), Some(sym::assert_macro))
4444
&& let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn)
4545
&& matches!(panic_expn, PanicExpn::Empty)
46-
&& let ExprKind::MethodCall(method_segment, [recv], _) = condition.kind
46+
&& let ExprKind::MethodCall(method_segment, recv, [], _) = condition.kind
4747
&& let result_type_with_refs = cx.typeck_results().expr_ty(recv)
4848
&& let result_type = result_type_with_refs.peel_refs()
4949
&& is_type_diagnostic_item(cx, result_type, sym::Result)

src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
5555
// do not lint if the closure is called using an iterator (see #1141)
5656
if_chain! {
5757
if let Some(parent) = get_parent_expr(self.cx, expr);
58-
if let ExprKind::MethodCall(_, [self_arg, ..], _) = &parent.kind;
58+
if let ExprKind::MethodCall(_, self_arg, ..) = &parent.kind;
5959
let caller = self.cx.typeck_results().expr_ty(self_arg);
6060
if let Some(iter_id) = self.cx.tcx.get_diagnostic_item(sym::Iterator);
6161
if implements_trait(self.cx, caller, iter_id, &[]);
@@ -117,7 +117,8 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInIfConditions {
117117
);
118118
}
119119
} else {
120-
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
120+
let span =
121+
block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
121122
if span.from_expansion() || expr.span.from_expansion() {
122123
return;
123124
}

src/tools/clippy/clippy_lints/src/booleans.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
270270
))
271271
})
272272
},
273-
ExprKind::MethodCall(path, args, _) if args.len() == 1 => {
274-
let type_of_receiver = cx.typeck_results().expr_ty(&args[0]);
273+
ExprKind::MethodCall(path, receiver, [], _) => {
274+
let type_of_receiver = cx.typeck_results().expr_ty(receiver);
275275
if !is_type_diagnostic_item(cx, type_of_receiver, sym::Option)
276276
&& !is_type_diagnostic_item(cx, type_of_receiver, sym::Result)
277277
{
@@ -285,7 +285,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
285285
let path: &str = path.ident.name.as_str();
286286
a == path
287287
})
288-
.and_then(|(_, neg_method)| Some(format!("{}.{}()", snippet_opt(cx, args[0].span)?, neg_method)))
288+
.and_then(|(_, neg_method)| Some(format!("{}.{}()", snippet_opt(cx, receiver.span)?, neg_method)))
289289
},
290290
_ => None,
291291
}

src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub(super) fn check(
2020
if meets_msrv(msrv, msrvs::UNSIGNED_ABS)
2121
&& let ty::Int(from) = cast_from.kind()
2222
&& let ty::Uint(to) = cast_to.kind()
23-
&& let ExprKind::MethodCall(method_path, args, _) = cast_expr.kind
23+
&& let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind
2424
&& method_path.ident.name.as_str() == "abs"
2525
{
2626
let span = if from.bit_width() == to.bit_width() {
@@ -37,7 +37,7 @@ pub(super) fn check(
3737
span,
3838
&format!("casting the result of `{cast_from}::abs()` to {cast_to}"),
3939
"replace with",
40-
format!("{}.unsigned_abs()", Sugg::hir(cx, &args[0], "..").maybe_par()),
40+
format!("{}.unsigned_abs()", Sugg::hir(cx, receiver, "..").maybe_par()),
4141
Applicability::MachineApplicable,
4242
);
4343
}

src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
4444
.saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
4545
_ => nbits,
4646
},
47-
ExprKind::MethodCall(method, [left, right], _) => {
47+
ExprKind::MethodCall(method, left, [right], _) => {
4848
if signed {
4949
return nbits;
5050
}
@@ -55,7 +55,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
5555
};
5656
apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::max_value()))
5757
},
58-
ExprKind::MethodCall(method, [_, lo, hi], _) => {
58+
ExprKind::MethodCall(method, _, [lo, hi], _) => {
5959
if method.ident.as_str() == "clamp" {
6060
//FIXME: make this a diagnostic item
6161
if let (Some(lo_bits), Some(hi_bits)) = (get_constant_bits(cx, lo), get_constant_bits(cx, hi)) {
@@ -64,7 +64,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
6464
}
6565
nbits
6666
},
67-
ExprKind::MethodCall(method, [_value], _) => {
67+
ExprKind::MethodCall(method, _value, [], _) => {
6868
if method.ident.name.as_str() == "signum" {
6969
0 // do not lint if cast comes from a `signum` function
7070
} else {

src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
1818
cx.typeck_results().expr_ty(expr),
1919
);
2020
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
21-
} else if let ExprKind::MethodCall(method_path, [self_arg, ..], _) = &expr.kind {
21+
} else if let ExprKind::MethodCall(method_path, self_arg, ..) = &expr.kind {
2222
if method_path.ident.name == sym!(cast)
2323
&& let Some(generic_args) = method_path.args
2424
&& let [GenericArg::Type(cast_to)] = generic_args.args
@@ -64,7 +64,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
6464
return false;
6565
};
6666
match parent.kind {
67-
ExprKind::MethodCall(name, [self_arg, ..], _) if self_arg.hir_id == e.hir_id => {
67+
ExprKind::MethodCall(name, self_arg, ..) if self_arg.hir_id == e.hir_id => {
6868
if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned")
6969
&& let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
7070
&& let Some(def_id) = cx.tcx.impl_of_method(def_id)

src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ fn should_lint(cx: &LateContext<'_>, cast_op: &Expr<'_>, cast_from: Ty<'_>, cast
4141
}
4242

4343
// Don't lint for the result of methods that always return non-negative values.
44-
if let ExprKind::MethodCall(path, _, _) = cast_op.kind {
44+
if let ExprKind::MethodCall(path, ..) = cast_op.kind {
4545
let mut method_name = path.ident.name.as_str();
4646
let allowed_methods = ["abs", "checked_abs", "rem_euclid", "checked_rem_euclid"];
4747

4848
if_chain! {
4949
if method_name == "unwrap";
5050
if let Some(arglist) = method_chain_args(cast_op, &["unwrap"]);
51-
if let ExprKind::MethodCall(inner_path, _, _) = &arglist[0][0].kind;
51+
if let ExprKind::MethodCall(inner_path, ..) = &arglist[0].0.kind;
5252
then {
5353
method_name = inner_path.ident.name.as_str();
5454
}

src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs

+11-12
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@ struct NumericFallbackVisitor<'a, 'tcx> {
6969

7070
impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
7171
fn new(cx: &'a LateContext<'tcx>) -> Self {
72-
Self {
73-
ty_bounds: vec![TyBound::Nothing],
74-
cx,
75-
}
72+
Self { ty_bounds: vec![TyBound::Nothing], cx }
7673
}
7774

7875
/// Check whether a passed literal has potential to cause fallback or not.
@@ -129,19 +126,21 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
129126
}
130127
return;
131128
}
132-
},
129+
}
133130

134-
ExprKind::MethodCall(_, args, _) => {
131+
ExprKind::MethodCall(_, receiver, args, _) => {
135132
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
136133
let fn_sig = self.cx.tcx.fn_sig(def_id).skip_binder();
137-
for (expr, bound) in iter::zip(*args, fn_sig.inputs()) {
134+
for (expr, bound) in
135+
iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs())
136+
{
138137
self.ty_bounds.push(TyBound::Ty(*bound));
139138
self.visit_expr(expr);
140139
self.ty_bounds.pop();
141140
}
142141
return;
143142
}
144-
},
143+
}
145144

146145
ExprKind::Struct(_, fields, base) => {
147146
let ty = self.cx.typeck_results().expr_ty(expr);
@@ -176,15 +175,15 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
176175
return;
177176
}
178177
}
179-
},
178+
}
180179

181180
ExprKind::Lit(lit) => {
182181
let ty = self.cx.typeck_results().expr_ty(expr);
183182
self.check_lit(lit, ty, expr.hir_id);
184183
return;
185-
},
184+
}
186185

187-
_ => {},
186+
_ => {}
188187
}
189188

190189
walk_expr(self, expr);
@@ -198,7 +197,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
198197
} else {
199198
self.ty_bounds.push(TyBound::Nothing);
200199
}
201-
},
200+
}
202201

203202
_ => self.ty_bounds.push(TyBound::Nothing),
204203
}

src/tools/clippy/clippy_lints/src/dereference.rs

+25-22
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ fn try_parse_ref_op<'tcx>(
581581
expr: &'tcx Expr<'_>,
582582
) -> Option<(RefOp, &'tcx Expr<'tcx>)> {
583583
let (def_id, arg) = match expr.kind {
584-
ExprKind::MethodCall(_, [arg], _) => (typeck.type_dependent_def_id(expr.hir_id)?, arg),
584+
ExprKind::MethodCall(_, arg, [], _) => (typeck.type_dependent_def_id(expr.hir_id)?, arg),
585585
ExprKind::Call(
586586
Expr {
587587
kind: ExprKind::Path(path),
@@ -796,16 +796,19 @@ fn walk_parents<'tcx>(
796796
},
797797
})
798798
}),
799-
ExprKind::MethodCall(_, args, _) => {
799+
ExprKind::MethodCall(_, receiver, args, _) => {
800800
let id = cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap();
801-
args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
802-
if i == 0 {
803-
// Check for calls to trait methods where the trait is implemented on a reference.
804-
// Two cases need to be handled:
805-
// * `self` methods on `&T` will never have auto-borrow
806-
// * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
807-
// priority.
808-
if e.hir_id != child_id {
801+
std::iter::once(receiver)
802+
.chain(args.iter())
803+
.position(|arg| arg.hir_id == child_id)
804+
.map(|i| {
805+
if i == 0 {
806+
// Check for calls to trait methods where the trait is implemented on a reference.
807+
// Two cases need to be handled:
808+
// * `self` methods on `&T` will never have auto-borrow
809+
// * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
810+
// priority.
811+
if e.hir_id != child_id {
809812
Position::ReborrowStable(precedence)
810813
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
811814
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
@@ -834,20 +837,20 @@ fn walk_parents<'tcx>(
834837
} else {
835838
Position::MethodReceiver
836839
}
837-
} else {
838-
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
839-
if let ty::Param(param_ty) = ty.kind() {
840-
needless_borrow_impl_arg_position(cx, parent, i, *param_ty, e, precedence, msrv)
841840
} else {
842-
ty_auto_deref_stability(
843-
cx,
844-
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i)),
845-
precedence,
846-
)
847-
.position_for_arg()
841+
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
842+
if let ty::Param(param_ty) = ty.kind() {
843+
needless_borrow_impl_arg_position(cx, parent, i, *param_ty, e, precedence, msrv)
844+
} else {
845+
ty_auto_deref_stability(
846+
cx,
847+
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i)),
848+
precedence,
849+
)
850+
.position_for_arg()
851+
}
848852
}
849-
}
850-
})
853+
})
851854
},
852855
ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(Position::FieldAccess(name.name)),
853856
ExprKind::Unary(UnOp::Deref, child) if child.hir_id == e.hir_id => Some(Position::Deref),

src/tools/clippy/clippy_lints/src/doc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
828828

829829
// check for `unwrap`
830830
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
831-
let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
831+
let receiver_ty = self.typeck_results.expr_ty(&arglists[0].0).peel_refs();
832832
if is_type_diagnostic_item(self.cx, receiver_ty, sym::Option)
833833
|| is_type_diagnostic_item(self.cx, receiver_ty, sym::Result)
834834
{

src/tools/clippy/clippy_lints/src/entry.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
245245
match expr.kind {
246246
ExprKind::MethodCall(
247247
_,
248+
map,
248249
[
249-
map,
250250
Expr {
251251
kind: ExprKind::AddrOf(_, _, key),
252252
span: key_span,
@@ -280,7 +280,7 @@ struct InsertExpr<'tcx> {
280280
value: &'tcx Expr<'tcx>,
281281
}
282282
fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
283-
if let ExprKind::MethodCall(_, [map, key, value], _) = expr.kind {
283+
if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
284284
let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
285285
if match_def_path(cx, id, &paths::BTREEMAP_INSERT) || match_def_path(cx, id, &paths::HASHMAP_INSERT) {
286286
Some(InsertExpr { map, key, value })

src/tools/clippy/clippy_lints/src/eta_reduction.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
106106
if !is_adjusted(cx, &body.value);
107107
if let ExprKind::Call(callee, args) = body.value.kind;
108108
if let ExprKind::Path(_) = callee.kind;
109-
if check_inputs(cx, body.params, args);
109+
if check_inputs(cx, body.params, None, args);
110110
let callee_ty = cx.typeck_results().expr_ty_adjusted(callee);
111111
let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id)
112112
.map_or(callee_ty, |id| cx.tcx.type_of(id));
@@ -146,8 +146,8 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
146146

147147
if_chain!(
148148
if !is_adjusted(cx, &body.value);
149-
if let ExprKind::MethodCall(path, args, _) = body.value.kind;
150-
if check_inputs(cx, body.params, args);
149+
if let ExprKind::MethodCall(path, receiver, args, _) = body.value.kind;
150+
if check_inputs(cx, body.params, Some(receiver), args);
151151
let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();
152152
let substs = cx.typeck_results().node_substs(body.value.hir_id);
153153
let call_ty = cx.tcx.bound_type_of(method_def_id).subst(cx.tcx, substs);
@@ -167,12 +167,17 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
167167
}
168168
}
169169

170-
fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_>]) -> bool {
171-
if params.len() != call_args.len() {
170+
fn check_inputs(
171+
cx: &LateContext<'_>,
172+
params: &[Param<'_>],
173+
receiver: Option<&Expr<'_>>,
174+
call_args: &[Expr<'_>],
175+
) -> bool {
176+
if receiver.map_or(params.len() != call_args.len(), |_| params.len() != call_args.len() + 1) {
172177
return false;
173178
}
174179
let binding_modes = cx.typeck_results().pat_binding_modes();
175-
std::iter::zip(params, call_args).all(|(param, arg)| {
180+
let check_inputs = |param: &Param<'_>, arg| {
176181
match param.pat.kind {
177182
PatKind::Binding(_, id, ..) if path_to_local_id(arg, id) => {},
178183
_ => return false,
@@ -200,7 +205,13 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_
200205
},
201206
_ => false,
202207
}
203-
})
208+
};
209+
if let Some(receiver) = receiver {
210+
std::iter::zip(params, std::iter::once(receiver).chain(call_args.iter()))
211+
.all(|(param, arg)| check_inputs(param, arg))
212+
} else {
213+
std::iter::zip(params, call_args).all(|(param, arg)| check_inputs(param, arg))
214+
}
204215
}
205216

206217
fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tcx>) -> bool {

src/tools/clippy/clippy_lints/src/explicit_write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
4545
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
4646
if_chain! {
4747
// match call to unwrap
48-
if let ExprKind::MethodCall(unwrap_fun, [write_call], _) = expr.kind;
48+
if let ExprKind::MethodCall(unwrap_fun, write_call, [], _) = expr.kind;
4949
if unwrap_fun.ident.name == sym::unwrap;
5050
// match call to write_fmt
51-
if let ExprKind::MethodCall(write_fun, [write_recv, write_arg], _) = look_in_block(cx, &write_call.kind);
51+
if let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = look_in_block(cx, &write_call.kind);
5252
if write_fun.ident.name == sym!(write_fmt);
5353
// match calls to std::io::stdout() / std::io::stderr ()
5454
if let Some(dest_name) = if match_function_call(cx, write_recv, &paths::STDOUT).is_some() {

0 commit comments

Comments
 (0)