refactor: remove unnecessary variables

This commit is contained in:
Takayuki Maeda 2022-09-02 22:48:14 +09:00
parent 3955dc3480
commit fea1c5f5c8
17 changed files with 93 additions and 108 deletions

View File

@ -906,7 +906,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let hir::ExprKind::Closure(hir::Closure {
capture_clause: hir::CaptureBy::Ref,
..
}) = arg.kind {
}) = arg.kind
{
closure_span = Some(arg.span.shrink_to_lo());
break;
}

View File

@ -1881,11 +1881,11 @@ pub enum ExprKind<'hir> {
///
/// The `PathSegment` represents the method name and its generic arguments
/// (within the angle brackets).
/// The first element of the `&[Expr]` is the expression that evaluates
/// The `&Expr` is the expression that evaluates
/// to the object on which the method is being called on (the receiver),
/// and the remaining elements are the rest of the arguments.
/// and the `&[Expr]` is the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d], span)`.
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d], span)`.
/// The final `Span` represents the span of the function and arguments
/// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)`
///

View File

@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
}
// We only care about method call expressions.
if let hir::ExprKind::MethodCall(call, receiver, ..) = &expr.kind {
if let hir::ExprKind::MethodCall(call, receiver_arg, ..) = &expr.kind {
if call.ident.name != sym::into_iter {
return;
}
@ -75,7 +75,6 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
};
// As this is a method call expression, we have at least one argument.
let receiver_arg = receiver;
let receiver_ty = cx.typeck_results().expr_ty(receiver_arg);
let adjustments = cx.typeck_results().expr_adjustments(receiver_arg);

View File

@ -63,15 +63,13 @@ impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr {
}
match first_method_call(expr) {
Some((path, receiver)) if path.ident.name == sym::as_ptr => {
let unwrap_arg = receiver;
Some((path, unwrap_arg)) if path.ident.name == sym::as_ptr => {
let as_ptr_span = path.ident.span;
match first_method_call(unwrap_arg) {
Some((path, receiver))
if path.ident.name == sym::unwrap || path.ident.name == sym::expect =>
{
let source_arg = receiver;
lint_cstring_as_ptr(cx, as_ptr_span, source_arg, unwrap_arg);
lint_cstring_as_ptr(cx, as_ptr_span, receiver, unwrap_arg);
}
_ => return,
}

View File

@ -267,7 +267,8 @@ impl<'tcx> Cx<'tcx> {
// When we apply adjustments to the receiver, use the span of
// the overall method call for better diagnostics. args[0]
// is guaranteed to exist, since a method call always has a receiver.
let old_adjustment_span = self.adjustment_span.replace((receiver.hir_id, expr_span));
let old_adjustment_span =
self.adjustment_span.replace((receiver.hir_id, expr_span));
info!("Using method span: {:?}", expr.span);
let args = std::iter::once(receiver)
.chain(args.iter())

View File

@ -1041,10 +1041,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprKind::MethodCall(.., receiver, ref args, _) => {
let succ = self.check_is_ty_uninhabited(expr, succ);
std::iter::once(receiver)
.chain(args.iter())
let succ = args
.iter()
.rev()
.fold(succ, |succ, expr| self.propagate_through_expr(expr, succ))
.fold(succ, |succ, expr| self.propagate_through_expr(expr, succ));
self.propagate_through_expr(receiver, succ)
}
hir::ExprKind::Tup(ref exprs) => self.propagate_through_exprs(exprs, succ),

View File

@ -770,16 +770,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let hir::ExprKind::MethodCall(ref segment, receiver, args, _) = expr.kind {
let clone_trait =
self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span));
if let (true, Some(true), sym::clone) = (
args.is_empty(),
self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
if args.is_empty()
&& self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
|did| {
let ai = self.tcx.associated_item(did);
ai.trait_container(self.tcx) == Some(clone_trait)
},
),
segment.ident.name,
) {
) == Some(true)
&& segment.ident.name == sym::clone
{
// If this expression had a clone call when suggesting borrowing
// we want to suggest removing it because it'd now be unnecessary.
sugg_sp = receiver.span;

View File

@ -1195,14 +1195,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr<'tcx>,
segment: &hir::PathSegment<'_>,
receiver: &'tcx hir::Expr<'tcx>,
rcvr: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
let rcvr = &receiver;
let rcvr_t = self.check_expr(&rcvr);
// no need to check for bot/err -- callee does that
let rcvr_t = self.structurally_resolved_type(receiver.span, rcvr_t);
let rcvr_t = self.structurally_resolved_type(rcvr.span, rcvr_t);
let span = segment.ident.span;
let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {
@ -1219,9 +1218,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
rcvr_t,
segment.ident,
SelfSource::MethodCall(receiver),
SelfSource::MethodCall(rcvr),
error,
Some((receiver, args)),
Some((rcvr, args)),
) {
err.emit();
}

View File

@ -1913,14 +1913,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.enumerate()
.filter(|(_, ty)| find_param_in_ty(**ty, param_to_point_at))
.collect();
let args: Vec<&'tcx hir::Expr<'tcx>> = if let Some(receiver) = receiver {
std::iter::once(receiver).chain(args.iter()).collect()
} else {
args.iter().collect()
};
// If there's one field that references the given generic, great!
if let [(idx, _)] = args_referencing_param.as_slice() && let Some(arg) = args.get(*idx) {
if let [(idx, _)] = args_referencing_param.as_slice()
&& let Some(arg) = receiver
.map_or(args.get(*idx), |rcvr| if *idx == 0 { Some(rcvr) } else { args.get(*idx - 1) }) {
error.obligation.cause.span = arg.span.find_ancestor_in_same_ctxt(error.obligation.cause.span).unwrap_or(arg.span);
error.obligation.cause.map_code(|parent_code| {
ObligationCauseCode::FunctionArgumentObligation {

View File

@ -798,57 +798,55 @@ fn walk_parents<'tcx>(
}),
ExprKind::MethodCall(_, receiver, args, _) => {
let id = cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap();
std::iter::once(receiver)
.chain(args.iter())
if receiver.hir_id == child_id {
// Check for calls to trait methods where the trait is implemented on a reference.
// Two cases need to be handled:
// * `self` methods on `&T` will never have auto-borrow
// * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
// priority.
if e.hir_id != child_id {
return Some(Position::ReborrowStable(precedence))
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let subs = match cx
.typeck_results()
.node_substs_opt(parent.hir_id)
.and_then(|subs| subs.get(1..))
{
Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
} && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
// Trait methods taking `&self`
sub_ty
} else {
// Trait methods taking `self`
arg_ty
} && impl_ty.is_ref()
&& cx.tcx.infer_ctxt().enter(|infcx|
infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions()
)
{
return Some(Position::MethodReceiverRefImpl)
} else {
return Some(Position::MethodReceiver)
}
}
args.iter()
.position(|arg| arg.hir_id == child_id)
.map(|i| {
if i == 0 {
// Check for calls to trait methods where the trait is implemented on a reference.
// Two cases need to be handled:
// * `self` methods on `&T` will never have auto-borrow
// * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take
// priority.
if e.hir_id != child_id {
Position::ReborrowStable(precedence)
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let subs = match cx
.typeck_results()
.node_substs_opt(parent.hir_id)
.and_then(|subs| subs.get(1..))
{
Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
} && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
// Trait methods taking `&self`
sub_ty
} else {
// Trait methods taking `self`
arg_ty
} && impl_ty.is_ref()
&& cx.tcx.infer_ctxt().enter(|infcx|
infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions()
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i + 1];
if let ty::Param(param_ty) = ty.kind() {
needless_borrow_impl_arg_position(cx, parent, i + 1, *param_ty, e, precedence, msrv)
} else {
ty_auto_deref_stability(
cx,
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i + 1)),
precedence,
)
{
Position::MethodReceiverRefImpl
} else {
Position::MethodReceiver
}
} else {
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
if let ty::Param(param_ty) = ty.kind() {
needless_borrow_impl_arg_position(cx, parent, i, *param_ty, e, precedence, msrv)
} else {
ty_auto_deref_stability(
cx,
cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).input(i)),
precedence,
)
.position_for_arg()
}
.position_for_arg()
}
})
},

View File

@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for InfiniteIter {
MaybeInfinite => (MAYBE_INFINITE_ITER, "possible infinite iteration detected"),
Finite => {
return;
},
}
};
span_lint(cx, lint, expr.span, msg);
}
@ -229,11 +229,9 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
return MaybeInfinite.and(is_infinite(cx, receiver));
}
}
if method.ident.name == sym!(last) {
let not_double_ended = cx
.tcx
.get_diagnostic_item(sym::DoubleEndedIterator)
.map_or(false, |id| {
if method.ident.name == sym!(last) && args.is_empty() {
let not_double_ended =
cx.tcx.get_diagnostic_item(sym::DoubleEndedIterator).map_or(false, |id| {
!implements_trait(cx, cx.typeck_results().expr_ty(receiver), id, &[])
});
if not_double_ended {

View File

@ -370,7 +370,7 @@ fn check_for_is_empty<'tcx>(
}
fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
if let (&ExprKind::MethodCall(method_path, receiver, ..), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind) {
if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref 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" {
@ -378,7 +378,7 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>
}
}
check_len(cx, span, method_path.ident.name, receiver, &lit.node, op, compare_to);
check_len(cx, span, method_path.ident.name, receiver, args, &lit.node, op, compare_to);
} else {
check_empty_expr(cx, span, method, lit, op);
}
@ -389,6 +389,7 @@ fn check_len(
span: Span,
method_name: Symbol,
receiver: &Expr<'_>,
args: &[Expr<'_>],
lit: &LitKind,
op: &str,
compare_to: u32,
@ -399,7 +400,7 @@ fn check_len(
return;
}
if method_name == sym::len && has_is_empty(cx, receiver) {
if method_name == sym::len && args.is_empty() && has_is_empty(cx, receiver) {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,

View File

@ -21,10 +21,7 @@ pub(super) fn check(
receiver: &Expr<'_>,
args: &[Expr<'_>],
) {
let arg = match args {
[] if method_name == sym::clone => receiver,
_ => return,
};
let arg = if method_name == sym::clone && args.is_empty() { receiver } else { return };
if cx
.typeck_results()
.type_dependent_def_id(expr.hir_id)

View File

@ -20,8 +20,7 @@ pub(super) fn check(
if !(args.is_empty() && method_name == sym::clone) {
return;
}
let arg = receiver;
let obj_ty = cx.typeck_results().expr_ty(arg).peel_refs();
let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
if let ty::Adt(_, subst) = obj_ty.kind() {
let caller_type = if is_type_diagnostic_item(cx, obj_ty, sym::Rc) {
@ -34,7 +33,7 @@ pub(super) fn check(
return;
};
let snippet = snippet_with_macro_callsite(cx, arg.span, "..");
let snippet = snippet_with_macro_callsite(cx, receiver.span, "..");
span_lint_and_sugg(
cx,

View File

@ -3381,7 +3381,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
impl Methods {
#[allow(clippy::too_many_lines)]
fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some((name, recv, [args @ ..], span)) = method_call(expr) {
if let Some((name, recv, args, span)) = method_call(expr) {
match (name, args) {
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
zst_offset::check(cx, expr, recv);
@ -3485,7 +3485,7 @@ impl Methods {
}
},
("last", []) | ("skip", [_]) => {
if let Some((name2, recv2, [args2 @ ..], _span2)) = method_call(recv) {
if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}
@ -3500,7 +3500,7 @@ impl Methods {
} else {
map_err_ignore::check(cx, expr, m_arg);
}
if let Some((name, recv2, [args @ ..], span2)) = method_call(recv) {
if let Some((name, recv2, args, span2)) = method_call(recv) {
match (name, args) {
("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),
("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),
@ -3520,7 +3520,7 @@ impl Methods {
manual_ok_or::check(cx, expr, recv, def, map);
},
("next", []) => {
if let Some((name2, recv2, [args2 @ ..], _)) = method_call(recv) {
if let Some((name2, recv2, args2, _)) = method_call(recv) {
match (name2, args2) {
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
@ -3593,7 +3593,7 @@ impl Methods {
},
("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
("take", [_arg]) => {
if let Some((name2, recv2, [args2 @ ..], _span2)) = method_call(recv) {
if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}

View File

@ -109,14 +109,12 @@ fn fetch_const<'a>(
args: &'a [Expr<'a>],
m: MinMax,
) -> Option<(MinMax, Constant, &'a Expr<'a>)> {
if (receiver.is_some() && args.len() != 1) || (receiver.is_none() && args.len() != 2) {
let mut args = receiver.into_iter().chain(args.into_iter());
let arg0 = args.next()?;
let arg1 = args.next()?;
if args.next().is_some() {
return None;
}
let (arg0, arg1) = if let Some(receiver) = receiver {
(receiver, &args[0])
} else {
(&args[0], &args[1])
};
constant_simple(cx, cx.typeck_results(), arg0).map_or_else(
|| constant_simple(cx, cx.typeck_results(), arg1).map(|c| (m, c, arg0)),
|c| {

View File

@ -150,7 +150,7 @@ impl<'tcx> Visitor<'_> for PeekableVisitor<'_, 'tcx> {
..
},
self_arg,
[remaining_args @ ..],
remaining_args,
_,
) => {
let method_name = method_name_ident.name.as_str();