separate the receiver from arguments in HIR under /clippy
This commit is contained in:
parent
9ae329232b
commit
4bcaddeeb2
111 changed files with 662 additions and 558 deletions
|
|
@ -118,9 +118,9 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
|
|||
ExprKind::Unary(UnOp::Neg, e) => (Pat::Str("-"), expr_search_pat(tcx, e).1),
|
||||
ExprKind::Lit(ref lit) => lit_search_pat(&lit.node),
|
||||
ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str("["), Pat::Str("]")),
|
||||
ExprKind::Call(e, []) | ExprKind::MethodCall(_, [e], _) => (expr_search_pat(tcx, e).0, Pat::Str("(")),
|
||||
ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => (expr_search_pat(tcx, e).0, Pat::Str("(")),
|
||||
ExprKind::Call(first, [.., last])
|
||||
| ExprKind::MethodCall(_, [first, .., last], _)
|
||||
| ExprKind::MethodCall(_, first, [.., last], _)
|
||||
| ExprKind::Binary(_, first, last)
|
||||
| ExprKind::Tup([first, .., last])
|
||||
| ExprKind::Assign(first, last, _)
|
||||
|
|
|
|||
|
|
@ -155,13 +155,7 @@ where
|
|||
});
|
||||
}
|
||||
|
||||
pub fn span_lint_hir(
|
||||
cx: &LateContext<'_>,
|
||||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
) {
|
||||
pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) {
|
||||
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| {
|
||||
let mut diag = diag.build(msg);
|
||||
docs_link(&mut diag, lint);
|
||||
|
|
|
|||
|
|
@ -45,12 +45,7 @@ impl ops::BitOrAssign for EagernessSuggestion {
|
|||
}
|
||||
|
||||
/// Determine the eagerness of the given function call.
|
||||
fn fn_eagerness<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
fn_id: DefId,
|
||||
name: Symbol,
|
||||
args: &'tcx [Expr<'_>],
|
||||
) -> EagernessSuggestion {
|
||||
fn fn_eagerness<'tcx>(cx: &LateContext<'tcx>, fn_id: DefId, name: Symbol, have_one_arg: bool) -> EagernessSuggestion {
|
||||
use EagernessSuggestion::{Eager, Lazy, NoChange};
|
||||
let name = name.as_str();
|
||||
|
||||
|
|
@ -59,7 +54,7 @@ fn fn_eagerness<'tcx>(
|
|||
None => return Lazy,
|
||||
};
|
||||
|
||||
if (name.starts_with("as_") || name == "len" || name == "is_empty") && args.len() == 1 {
|
||||
if (name.starts_with("as_") || name == "len" || name == "is_empty") && have_one_arg {
|
||||
if matches!(
|
||||
cx.tcx.crate_name(fn_id.krate),
|
||||
sym::std | sym::core | sym::alloc | sym::proc_macro
|
||||
|
|
@ -127,10 +122,11 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
|||
},
|
||||
Res::Def(_, id) => match path {
|
||||
QPath::Resolved(_, p) => {
|
||||
self.eagerness |= fn_eagerness(self.cx, id, p.segments.last().unwrap().ident.name, args);
|
||||
self.eagerness |=
|
||||
fn_eagerness(self.cx, id, p.segments.last().unwrap().ident.name, !args.is_empty());
|
||||
},
|
||||
QPath::TypeRelative(_, name) => {
|
||||
self.eagerness |= fn_eagerness(self.cx, id, name.ident.name, args);
|
||||
self.eagerness |= fn_eagerness(self.cx, id, name.ident.name, !args.is_empty());
|
||||
},
|
||||
QPath::LangItem(..) => self.eagerness = Lazy,
|
||||
},
|
||||
|
|
@ -141,12 +137,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
|
|||
self.eagerness |= NoChange;
|
||||
return;
|
||||
},
|
||||
ExprKind::MethodCall(name, args, _) => {
|
||||
ExprKind::MethodCall(name, ..) => {
|
||||
self.eagerness |= self
|
||||
.cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(e.hir_id)
|
||||
.map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, args));
|
||||
.map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));
|
||||
},
|
||||
ExprKind::Index(_, e) => {
|
||||
let ty = self.cx.typeck_results().expr_ty_adjusted(e);
|
||||
|
|
|
|||
|
|
@ -282,8 +282,14 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
&& self.eq_expr(l.body, r.body)
|
||||
})
|
||||
},
|
||||
(&ExprKind::MethodCall(l_path, l_args, _), &ExprKind::MethodCall(r_path, r_args, _)) => {
|
||||
self.inner.allow_side_effects && self.eq_path_segment(l_path, r_path) && self.eq_exprs(l_args, r_args)
|
||||
(
|
||||
&ExprKind::MethodCall(l_path, l_receiver, l_args, _),
|
||||
&ExprKind::MethodCall(r_path, r_receiver, r_args, _),
|
||||
) => {
|
||||
self.inner.allow_side_effects
|
||||
&& self.eq_path_segment(l_path, r_path)
|
||||
&& self.eq_expr(l_receiver, r_receiver)
|
||||
&& self.eq_exprs(l_args, r_args)
|
||||
},
|
||||
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
|
||||
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
|
||||
|
|
@ -743,8 +749,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
|
||||
s.hash(&mut self.s);
|
||||
},
|
||||
ExprKind::MethodCall(path, args, ref _fn_span) => {
|
||||
ExprKind::MethodCall(path, receiver, args, ref _fn_span) => {
|
||||
self.hash_name(path.ident.name);
|
||||
self.hash_expr(receiver);
|
||||
self.hash_exprs(args);
|
||||
},
|
||||
ExprKind::ConstBlock(ref l_id) => {
|
||||
|
|
|
|||
|
|
@ -1036,21 +1036,21 @@ pub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'
|
|||
pub fn method_calls<'tcx>(
|
||||
expr: &'tcx Expr<'tcx>,
|
||||
max_depth: usize,
|
||||
) -> (Vec<Symbol>, Vec<&'tcx [Expr<'tcx>]>, Vec<Span>) {
|
||||
) -> (Vec<Symbol>, Vec<(&'tcx Expr<'tcx>, &'tcx [Expr<'tcx>])>, Vec<Span>) {
|
||||
let mut method_names = Vec::with_capacity(max_depth);
|
||||
let mut arg_lists = Vec::with_capacity(max_depth);
|
||||
let mut spans = Vec::with_capacity(max_depth);
|
||||
|
||||
let mut current = expr;
|
||||
for _ in 0..max_depth {
|
||||
if let ExprKind::MethodCall(path, args, _) = ¤t.kind {
|
||||
if args.iter().any(|e| e.span.from_expansion()) {
|
||||
if let ExprKind::MethodCall(path, receiver, args, _) = ¤t.kind {
|
||||
if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {
|
||||
break;
|
||||
}
|
||||
method_names.push(path.ident.name);
|
||||
arg_lists.push(&**args);
|
||||
arg_lists.push((*receiver, &**args));
|
||||
spans.push(path.ident.span);
|
||||
current = &args[0];
|
||||
current = receiver;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
@ -1065,18 +1065,18 @@ pub fn method_calls<'tcx>(
|
|||
/// `method_chain_args(expr, &["bar", "baz"])` will return a `Vec`
|
||||
/// containing the `Expr`s for
|
||||
/// `.bar()` and `.baz()`
|
||||
pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<&'a [Expr<'a>]>> {
|
||||
pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<(&'a Expr<'a>, &'a [Expr<'a>])>> {
|
||||
let mut current = expr;
|
||||
let mut matched = Vec::with_capacity(methods.len());
|
||||
for method_name in methods.iter().rev() {
|
||||
// method chains are stored last -> first
|
||||
if let ExprKind::MethodCall(path, args, _) = current.kind {
|
||||
if let ExprKind::MethodCall(path, receiver, args, _) = current.kind {
|
||||
if path.ident.name.as_str() == *method_name {
|
||||
if args.iter().any(|e| e.span.from_expansion()) {
|
||||
if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {
|
||||
return None;
|
||||
}
|
||||
matched.push(args); // build up `matched` backwards
|
||||
current = &args[0]; // go to parent expression
|
||||
matched.push((receiver, args)); // build up `matched` backwards
|
||||
current = receiver; // go to parent expression
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -1239,8 +1239,10 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
|
|||
ty_is_fn_once_param(cx.tcx, ty.skip_binder(), predicates).then_some(())
|
||||
})
|
||||
},
|
||||
ExprKind::MethodCall(_, args, _) => {
|
||||
let i = args.iter().position(|arg| arg.hir_id == id)?;
|
||||
ExprKind::MethodCall(_, receiver, args, _) => {
|
||||
let i = std::iter::once(receiver)
|
||||
.chain(args.iter())
|
||||
.position(|arg| arg.hir_id == id)?;
|
||||
let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
|
||||
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i];
|
||||
ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ fn extract_clone_suggestions<'tcx>(
|
|||
if abort {
|
||||
return false;
|
||||
}
|
||||
if let ExprKind::MethodCall(seg, [recv], _) = expr.kind {
|
||||
if let ExprKind::MethodCall(seg, recv, [], _) = expr.kind {
|
||||
if path_to_local_id(recv, id) {
|
||||
if seg.ident.name.as_str() == "capacity" {
|
||||
abort = true;
|
||||
|
|
|
|||
|
|
@ -373,12 +373,14 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
|
|||
| AssocOp::LessEqual
|
||||
| AssocOp::NotEqual
|
||||
| AssocOp::Greater
|
||||
| AssocOp::GreaterEqual => format!(
|
||||
"{} {} {}",
|
||||
lhs,
|
||||
op.to_ast_binop().expect("Those are AST ops").to_string(),
|
||||
rhs
|
||||
),
|
||||
| AssocOp::GreaterEqual => {
|
||||
format!(
|
||||
"{} {} {}",
|
||||
lhs,
|
||||
op.to_ast_binop().expect("Those are AST ops").to_string(),
|
||||
rhs
|
||||
)
|
||||
},
|
||||
AssocOp::Assign => format!("{} = {}", lhs, rhs),
|
||||
AssocOp::AssignOp(op) => {
|
||||
format!("{} {}= {}", lhs, token_kind_to_string(&token::BinOp(op)), rhs)
|
||||
|
|
@ -868,15 +870,15 @@ impl<'tcx> DerefDelegate<'_, 'tcx> {
|
|||
/// indicates whether the function from `parent_expr` takes its args by double reference
|
||||
fn func_takes_arg_by_double_ref(&self, parent_expr: &'tcx hir::Expr<'_>, cmt_hir_id: HirId) -> bool {
|
||||
let ty = match parent_expr.kind {
|
||||
ExprKind::MethodCall(_, call_args, _) => {
|
||||
ExprKind::MethodCall(_, receiver, call_args, _) => {
|
||||
if let Some(sig) = self
|
||||
.cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(parent_expr.hir_id)
|
||||
.map(|did| self.cx.tcx.fn_sig(did).skip_binder())
|
||||
{
|
||||
call_args
|
||||
.iter()
|
||||
std::iter::once(receiver)
|
||||
.chain(call_args.iter())
|
||||
.position(|arg| arg.hir_id == cmt_hir_id)
|
||||
.map(|i| sig.inputs()[i])
|
||||
} else {
|
||||
|
|
@ -933,14 +935,14 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
|
|||
match &parent_expr.kind {
|
||||
// given expression is the self argument and will be handled completely by the compiler
|
||||
// i.e.: `|x| x.is_something()`
|
||||
ExprKind::MethodCall(_, [self_expr, ..], _) if self_expr.hir_id == cmt.hir_id => {
|
||||
ExprKind::MethodCall(_, self_expr, ..) if self_expr.hir_id == cmt.hir_id => {
|
||||
let _ = write!(self.suggestion_start, "{}{}", start_snip, ident_str_with_proj);
|
||||
self.next_pos = span.hi();
|
||||
return;
|
||||
},
|
||||
// item is used in a call
|
||||
// i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)`
|
||||
ExprKind::Call(_, [call_args @ ..]) | ExprKind::MethodCall(_, [_, call_args @ ..], _) => {
|
||||
ExprKind::Call(_, [call_args @ ..]) | ExprKind::MethodCall(_, _, [call_args @ ..], _) => {
|
||||
let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id);
|
||||
let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind();
|
||||
|
||||
|
|
|
|||
|
|
@ -620,7 +620,13 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
helper(typeck, true, arg, f)?;
|
||||
}
|
||||
},
|
||||
ExprKind::MethodCall(_, args, _) | ExprKind::Tup(args) | ExprKind::Array(args) => {
|
||||
ExprKind::MethodCall(_, receiver, args, _) => {
|
||||
helper(typeck, true, receiver, f)?;
|
||||
for arg in args {
|
||||
helper(typeck, true, arg, f)?;
|
||||
}
|
||||
},
|
||||
ExprKind::Tup(args) | ExprKind::Array(args) => {
|
||||
for arg in args {
|
||||
helper(typeck, true, arg, f)?;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue