Merge remote-tracking branch 'upstream/master' into rustup
This commit is contained in:
commit
bbcde66685
323 changed files with 3669 additions and 1716 deletions
|
|
@ -85,7 +85,7 @@ pub(crate) trait BindInsteadOfMap {
|
|||
|
||||
let closure_args_snip = snippet(cx, closure_args_span, "..");
|
||||
let option_snip = snippet(cx, recv.span, "..");
|
||||
let note = format!("{}.{}({} {})", option_snip, Self::GOOD_METHOD_NAME, closure_args_snip, some_inner_snip);
|
||||
let note = format!("{option_snip}.{}({closure_args_snip} {some_inner_snip})", Self::GOOD_METHOD_NAME);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
BIND_INSTEAD_OF_MAP,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
|
|||
cx,
|
||||
BYTES_NTH,
|
||||
expr.span,
|
||||
&format!("called `.bytes().nth()` on a `{}`", caller_type),
|
||||
&format!("called `.bytes().nth()` on a `{caller_type}`"),
|
||||
"try",
|
||||
format!(
|
||||
"{}.as_bytes().get({})",
|
||||
|
|
|
|||
|
|
@ -33,12 +33,11 @@ pub(super) fn check(
|
|||
cx,
|
||||
lint,
|
||||
info.expr.span,
|
||||
&format!("you should use the `{}` method", suggest),
|
||||
&format!("you should use the `{suggest}` method"),
|
||||
"like this",
|
||||
format!("{}{}.{}({})",
|
||||
format!("{}{}.{suggest}({})",
|
||||
if info.eq { "" } else { "!" },
|
||||
snippet_with_applicability(cx, args[0].0.span, "..", &mut applicability),
|
||||
suggest,
|
||||
snippet_with_applicability(cx, arg_char.span, "..", &mut applicability)),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
lint,
|
||||
info.expr.span,
|
||||
&format!("you should use the `{}` method", suggest),
|
||||
&format!("you should use the `{suggest}` method"),
|
||||
"like this",
|
||||
format!("{}{}.{}('{}')",
|
||||
format!("{}{}.{suggest}('{}')",
|
||||
if info.eq { "" } else { "!" },
|
||||
snippet_with_applicability(cx, args[0].0.span, "..", &mut applicability),
|
||||
suggest,
|
||||
c.escape_default()),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@ pub(super) fn check(
|
|||
expr.span,
|
||||
&format!(
|
||||
"using `clone` on a double-reference; \
|
||||
this will copy the reference of type `{}` instead of cloning the inner type",
|
||||
ty
|
||||
this will copy the reference of type `{ty}` instead of cloning the inner type"
|
||||
),
|
||||
|diag| {
|
||||
if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
|
||||
|
|
@ -62,11 +61,11 @@ pub(super) fn check(
|
|||
}
|
||||
let refs = "&".repeat(n + 1);
|
||||
let derefs = "*".repeat(n);
|
||||
let explicit = format!("<{}{}>::clone({})", refs, ty, snip);
|
||||
let explicit = format!("<{refs}{ty}>::clone({snip})");
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try dereferencing it",
|
||||
format!("{}({}{}).clone()", refs, derefs, snip.deref()),
|
||||
format!("{refs}({derefs}{}).clone()", snip.deref()),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
diag.span_suggestion(
|
||||
|
|
@ -121,16 +120,16 @@ pub(super) fn check(
|
|||
let (help, sugg) = if deref_count == 0 {
|
||||
("try removing the `clone` call", snip.into())
|
||||
} else if parent_is_suffix_expr {
|
||||
("try dereferencing it", format!("({}{})", "*".repeat(deref_count), snip))
|
||||
("try dereferencing it", format!("({}{snip})", "*".repeat(deref_count)))
|
||||
} else {
|
||||
("try dereferencing it", format!("{}{}", "*".repeat(deref_count), snip))
|
||||
("try dereferencing it", format!("{}{snip}", "*".repeat(deref_count)))
|
||||
};
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
CLONE_ON_COPY,
|
||||
expr.span,
|
||||
&format!("using `clone` on type `{}` which implements the `Copy` trait", ty),
|
||||
&format!("using `clone` on type `{ty}` which implements the `Copy` trait"),
|
||||
help,
|
||||
sugg,
|
||||
app,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ pub(super) fn check(
|
|||
expr.span,
|
||||
"using `.clone()` on a ref-counted pointer",
|
||||
"try this",
|
||||
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet),
|
||||
format!("{caller_type}::<{}>::clone(&{snippet})", subst.type_at(0)),
|
||||
Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
EXPECT_FUN_CALL,
|
||||
span_replace_word,
|
||||
&format!("use of `{}` followed by a function call", name),
|
||||
&format!("use of `{name}` followed by a function call"),
|
||||
"try this",
|
||||
format!("unwrap_or_else({} panic!({}))", closure_args, sugg),
|
||||
format!("unwrap_or_else({closure_args} panic!({sugg}))"),
|
||||
applicability,
|
||||
);
|
||||
return;
|
||||
|
|
@ -160,12 +160,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
EXPECT_FUN_CALL,
|
||||
span_replace_word,
|
||||
&format!("use of `{}` followed by a function call", name),
|
||||
&format!("use of `{name}` followed by a function call"),
|
||||
"try this",
|
||||
format!(
|
||||
"unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})",
|
||||
closure_args, arg_root_snippet
|
||||
),
|
||||
format!("unwrap_or_else({closure_args} {{ panic!(\"{{}}\", {arg_root_snippet}) }})"),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
|||
span = expr.span;
|
||||
}
|
||||
}
|
||||
let lint_msg = format!("`{}FileType::is_file()` only {} regular files", lint_unary, verb);
|
||||
let help_msg = format!("use `{}FileType::is_dir()` instead", help_unary);
|
||||
let lint_msg = format!("`{lint_unary}FileType::is_file()` only {verb} regular files");
|
||||
let help_msg = format!("use `{help_unary}FileType::is_dir()` instead");
|
||||
span_lint_and_help(cx, FILETYPE_IS_FILE, span, &lint_msg, None, &help_msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try this",
|
||||
format!("{}.find_map({})", iter_snippet, filter_snippet),
|
||||
format!("{iter_snippet}.find_map({filter_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try this",
|
||||
format!("{}.find({})", iter_snippet, filter_snippet),
|
||||
format!("{iter_snippet}.find({filter_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Exp
|
|||
// `expr` implements `FromIterator` trait
|
||||
let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par();
|
||||
let turbofish = extract_turbofish(cx, expr, ty);
|
||||
let sugg = format!("{}.collect::<{}>()", iter_expr, turbofish);
|
||||
let sugg = format!("{iter_expr}.collect::<{turbofish}>()");
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
|
|
@ -63,7 +63,7 @@ fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'_>) ->
|
|||
if e == type_specifier { None } else { Some((*e).to_string()) }
|
||||
}).collect::<Vec<_>>();
|
||||
// join and add the type specifier at the end (i.e.: `collections::BTreeSet<u32>`)
|
||||
format!("{}{}", without_ts.join("::"), type_specifier)
|
||||
format!("{}{type_specifier}", without_ts.join("::"))
|
||||
} else {
|
||||
// type is not explicitly specified so wildcards are needed
|
||||
// i.e.: 2 wildcards in `std::collections::BTreeMap<&i32, &char>`
|
||||
|
|
@ -72,7 +72,7 @@ fn extract_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>, ty: Ty<'_>) ->
|
|||
let end = ty_str.find('>').unwrap_or(ty_str.len());
|
||||
let nb_wildcard = ty_str[start..end].split(',').count();
|
||||
let wildcards = format!("_{}", ", _".repeat(nb_wildcard - 1));
|
||||
format!("{}<{}>", elements.join("::"), wildcards)
|
||||
format!("{}<{wildcards}>", elements.join("::"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
GET_FIRST,
|
||||
expr.span,
|
||||
&format!("accessing first element with `{0}.get(0)`", slice_name),
|
||||
&format!("accessing first element with `{slice_name}.get(0)`"),
|
||||
"try",
|
||||
format!("{}.first()", slice_name),
|
||||
format!("{slice_name}.first()"),
|
||||
app,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,16 +71,11 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
GET_UNWRAP,
|
||||
span,
|
||||
&format!(
|
||||
"called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise",
|
||||
mut_str, caller_type
|
||||
),
|
||||
&format!("called `.get{mut_str}().unwrap()` on a {caller_type}. Using `[]` is more clear and more concise"),
|
||||
"try this",
|
||||
format!(
|
||||
"{}{}[{}]",
|
||||
borrow_str,
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
|
||||
get_args_str
|
||||
"{borrow_str}{}[{get_args_str}]",
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
|
|||
cx,
|
||||
IMPLICIT_CLONE,
|
||||
expr.span,
|
||||
&format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_name),
|
||||
&format!("implicitly cloning a `{ty_name}` by calling `{method_name}` on its dereferenced type"),
|
||||
"consider using",
|
||||
if ref_count > 1 {
|
||||
format!("({}{}).clone()", "*".repeat(ref_count - 1), recv_snip)
|
||||
format!("({}{recv_snip}).clone()", "*".repeat(ref_count - 1))
|
||||
} else {
|
||||
format!("{}.clone()", recv_snip)
|
||||
format!("{recv_snip}.clone()")
|
||||
},
|
||||
app,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,18 +34,17 @@ pub fn check<'tcx>(
|
|||
cx,
|
||||
INEFFICIENT_TO_STRING,
|
||||
expr.span,
|
||||
&format!("calling `to_string` on `{}`", arg_ty),
|
||||
&format!("calling `to_string` on `{arg_ty}`"),
|
||||
|diag| {
|
||||
diag.help(&format!(
|
||||
"`{}` implements `ToString` through a slower blanket impl, but `{}` has a fast specialization of `ToString`",
|
||||
self_ty, deref_self_ty
|
||||
"`{self_ty}` implements `ToString` through a slower blanket impl, but `{deref_self_ty}` has a fast specialization of `ToString`"
|
||||
));
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let arg_snippet = snippet_with_applicability(cx, receiver.span, "..", &mut applicability);
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try dereferencing the receiver",
|
||||
format!("({}{}).to_string()", "*".repeat(deref_count), arg_snippet),
|
||||
format!("({}{arg_snippet}).to_string()", "*".repeat(deref_count)),
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ pub(super) fn check(
|
|||
INTO_ITER_ON_REF,
|
||||
method_span,
|
||||
&format!(
|
||||
"this `.into_iter()` call is equivalent to `.{}()` and will not consume the `{}`",
|
||||
method_name, kind,
|
||||
"this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`",
|
||||
),
|
||||
"call directly",
|
||||
method_name.to_string(),
|
||||
|
|
|
|||
|
|
@ -37,12 +37,11 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
IS_DIGIT_ASCII_RADIX,
|
||||
expr.span,
|
||||
&format!("use of `char::is_digit` with literal radix of {}", num),
|
||||
&format!("use of `char::is_digit` with literal radix of {num}"),
|
||||
"try",
|
||||
format!(
|
||||
"{}.{}()",
|
||||
snippet_with_applicability(cx, self_arg.span, "..", &mut applicability),
|
||||
replacement
|
||||
"{}.{replacement}()",
|
||||
snippet_with_applicability(cx, self_arg.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, method_name: &str, expr: &hir:
|
|||
cx,
|
||||
ITER_CLONED_COLLECT,
|
||||
to_replace,
|
||||
&format!("called `iter().{}().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \
|
||||
more readable", method_name),
|
||||
&format!("called `iter().{method_name}().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \
|
||||
more readable"),
|
||||
"try",
|
||||
".to_vec()".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
|
|||
cx,
|
||||
ITER_COUNT,
|
||||
expr.span,
|
||||
&format!("called `.{}().count()` on a `{}`", iter_method, caller_type),
|
||||
&format!("called `.{iter_method}().count()` on a `{caller_type}`"),
|
||||
"try",
|
||||
format!(
|
||||
"{}.len()",
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
ITER_KV_MAP,
|
||||
expr.span,
|
||||
&format!("iterating on a map's {}s", replacement_kind),
|
||||
&format!("iterating on a map's {replacement_kind}s"),
|
||||
"try",
|
||||
format!("{}.{}{}s()", recv_snippet, into_prefix, replacement_kind),
|
||||
format!("{recv_snippet}.{into_prefix}{replacement_kind}s()"),
|
||||
applicability,
|
||||
);
|
||||
} else {
|
||||
|
|
@ -64,9 +64,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
ITER_KV_MAP,
|
||||
expr.span,
|
||||
&format!("iterating on a map's {}s", replacement_kind),
|
||||
&format!("iterating on a map's {replacement_kind}s"),
|
||||
"try",
|
||||
format!("{}.{}{}s().map(|{}| {})", recv_snippet, into_prefix, replacement_kind, binded_ident,
|
||||
format!("{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{binded_ident}| {})",
|
||||
snippet_with_applicability(cx, body_expr.span, "/* body */", &mut applicability)),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, cal
|
|||
let suggest = if start_idx == 0 {
|
||||
format!("{}.first()", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability))
|
||||
} else {
|
||||
format!("{}.get({})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability), start_idx)
|
||||
format!("{}.get({start_idx})", snippet_with_applicability(cx, caller_var.span, "..", &mut applicability))
|
||||
};
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
ITER_NTH,
|
||||
expr.span,
|
||||
&format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type),
|
||||
&format!("called `.iter{mut_str}().nth()` on a {caller_type}"),
|
||||
None,
|
||||
&format!("calling `.get{}()` is both faster and more readable", mut_str),
|
||||
&format!("calling `.get{mut_str}()` is both faster and more readable"),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
|
|||
cx,
|
||||
ITER_WITH_DRAIN,
|
||||
span.with_hi(expr.span.hi()),
|
||||
&format!("`drain(..)` used on a `{}`", ty_name),
|
||||
&format!("`drain(..)` used on a `{ty_name}`"),
|
||||
"try this",
|
||||
"into_iter()".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
|
|||
|
|
@ -37,9 +37,7 @@ pub(super) fn check<'tcx>(
|
|||
"this pattern reimplements `Option::ok_or`",
|
||||
"replace with",
|
||||
format!(
|
||||
"{}.ok_or({})",
|
||||
recv_snippet,
|
||||
reindented_err_arg_snippet
|
||||
"{recv_snippet}.ok_or({reindented_err_arg_snippet})"
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -57,11 +57,10 @@ pub fn check(
|
|||
super::MANUAL_SATURATING_ARITHMETIC,
|
||||
expr.span,
|
||||
"manual saturating arithmetic",
|
||||
&format!("try using `saturating_{}`", arith),
|
||||
&format!("try using `saturating_{arith}`"),
|
||||
format!(
|
||||
"{}.saturating_{}({})",
|
||||
"{}.saturating_{arith}({})",
|
||||
snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability),
|
||||
arith,
|
||||
snippet_with_applicability(cx, arith_rhs.span, "..", &mut applicability),
|
||||
),
|
||||
applicability,
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ pub(super) fn check(
|
|||
collect_expr.span,
|
||||
"manual implementation of `str::repeat` using iterators",
|
||||
"try this",
|
||||
format!("{}.repeat({})", val_str, count_snip),
|
||||
format!("{val_str}.repeat({count_snip})"),
|
||||
app
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,11 +111,10 @@ fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_cop
|
|||
MAP_CLONE,
|
||||
replace,
|
||||
message,
|
||||
&format!("consider calling the dedicated `{}` method", sugg_method),
|
||||
&format!("consider calling the dedicated `{sugg_method}` method"),
|
||||
format!(
|
||||
"{}.{}()",
|
||||
"{}.{sugg_method}()",
|
||||
snippet_with_applicability(cx, root, "..", &mut applicability),
|
||||
sugg_method,
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, map_
|
|||
cx,
|
||||
MAP_FLATTEN,
|
||||
expr.span.with_lo(map_span.lo()),
|
||||
&format!("called `map(..).flatten()` on `{}`", caller_ty_name),
|
||||
&format!(
|
||||
"try replacing `map` with `{}` and remove the `.flatten()`",
|
||||
method_to_use
|
||||
),
|
||||
format!("{}({})", method_to_use, closure_snippet),
|
||||
&format!("called `map(..).flatten()` on `{caller_ty_name}`"),
|
||||
&format!("try replacing `map` with `{method_to_use}` and remove the `.flatten()`"),
|
||||
format!("{method_to_use}({closure_snippet})"),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ pub(super) fn check(
|
|||
MAP_IDENTITY,
|
||||
sugg_span,
|
||||
"unnecessary map of the identity function",
|
||||
&format!("remove the call to `{}`", name),
|
||||
&format!("remove the call to `{name}`"),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try this",
|
||||
format!("{}.map_or_else({}, {})", var_snippet, unwrap_snippet, map_snippet),
|
||||
format!("{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -109,13 +109,13 @@ use if_chain::if_chain;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TraitItem, TraitItemKind};
|
||||
use rustc_hir_analysis::hir_ty_to_ty;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_hir_analysis::hir_ty_to_ty;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -3255,65 +3255,59 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
let self_ty = cx.tcx.type_of(item.def_id);
|
||||
|
||||
let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
|
||||
if_chain! {
|
||||
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind;
|
||||
if let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next();
|
||||
|
||||
let method_sig = cx.tcx.fn_sig(impl_item.def_id.def_id);
|
||||
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
|
||||
let method_sig = cx.tcx.fn_sig(impl_item.def_id);
|
||||
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
|
||||
|
||||
let first_arg_ty = method_sig.inputs().iter().next();
|
||||
|
||||
// check conventions w.r.t. conversion method names and predicates
|
||||
if let Some(first_arg_ty) = first_arg_ty;
|
||||
|
||||
then {
|
||||
// if this impl block implements a trait, lint in trait definition instead
|
||||
if !implements_trait && cx.access_levels.is_exported(impl_item.def_id.def_id) {
|
||||
// check missing trait implementations
|
||||
for method_config in &TRAIT_METHODS {
|
||||
if name == method_config.method_name &&
|
||||
sig.decl.inputs.len() == method_config.param_count &&
|
||||
method_config.output_type.matches(&sig.decl.output) &&
|
||||
method_config.self_kind.matches(cx, self_ty, *first_arg_ty) &&
|
||||
fn_header_equals(method_config.fn_header, sig.header) &&
|
||||
method_config.lifetime_param_cond(impl_item)
|
||||
{
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
SHOULD_IMPLEMENT_TRAIT,
|
||||
impl_item.span,
|
||||
&format!(
|
||||
"method `{}` can be confused for the standard trait method `{}::{}`",
|
||||
method_config.method_name,
|
||||
method_config.trait_name,
|
||||
method_config.method_name
|
||||
),
|
||||
None,
|
||||
&format!(
|
||||
"consider implementing the trait `{}` or choosing a less ambiguous method name",
|
||||
method_config.trait_name
|
||||
)
|
||||
);
|
||||
}
|
||||
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
|
||||
// if this impl block implements a trait, lint in trait definition instead
|
||||
if !implements_trait && cx.access_levels.is_exported(impl_item.def_id.def_id) {
|
||||
// check missing trait implementations
|
||||
for method_config in &TRAIT_METHODS {
|
||||
if name == method_config.method_name
|
||||
&& sig.decl.inputs.len() == method_config.param_count
|
||||
&& method_config.output_type.matches(&sig.decl.output)
|
||||
// in case there is no first arg, since we already have checked the number of arguments
|
||||
// it's should be always true
|
||||
&& first_arg_ty_opt.map_or(true, |first_arg_ty| method_config
|
||||
.self_kind.matches(cx, self_ty, first_arg_ty)
|
||||
)
|
||||
&& fn_header_equals(method_config.fn_header, sig.header)
|
||||
&& method_config.lifetime_param_cond(impl_item)
|
||||
{
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
SHOULD_IMPLEMENT_TRAIT,
|
||||
impl_item.span,
|
||||
&format!(
|
||||
"method `{}` can be confused for the standard trait method `{}::{}`",
|
||||
method_config.method_name, method_config.trait_name, method_config.method_name
|
||||
),
|
||||
None,
|
||||
&format!(
|
||||
"consider implementing the trait `{}` or choosing a less ambiguous method name",
|
||||
method_config.trait_name
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sig.decl.implicit_self.has_implicit_self()
|
||||
if sig.decl.implicit_self.has_implicit_self()
|
||||
&& !(self.avoid_breaking_exported_api
|
||||
&& cx.access_levels.is_exported(impl_item.def_id.def_id))
|
||||
&& cx.access_levels.is_exported(impl_item.def_id.def_id))
|
||||
&& let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next()
|
||||
&& let Some(first_arg_ty) = first_arg_ty_opt
|
||||
{
|
||||
wrong_self_convention::check(
|
||||
cx,
|
||||
name,
|
||||
self_ty,
|
||||
*first_arg_ty,
|
||||
first_arg_ty,
|
||||
first_arg.pat.span,
|
||||
implements_trait,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if this impl block implements a trait, lint in trait definition instead
|
||||
|
|
@ -3799,7 +3793,6 @@ const TRAIT_METHODS: [ShouldImplTraitCase; 30] = [
|
|||
ShouldImplTraitCase::new("std::borrow::BorrowMut", "borrow_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true),
|
||||
ShouldImplTraitCase::new("std::clone::Clone", "clone", 1, FN_HEADER, SelfKind::Ref, OutType::Any, true),
|
||||
ShouldImplTraitCase::new("std::cmp::Ord", "cmp", 2, FN_HEADER, SelfKind::Ref, OutType::Any, true),
|
||||
// FIXME: default doesn't work
|
||||
ShouldImplTraitCase::new("std::default::Default", "default", 0, FN_HEADER, SelfKind::No, OutType::Any, true),
|
||||
ShouldImplTraitCase::new("std::ops::Deref", "deref", 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true),
|
||||
ShouldImplTraitCase::new("std::ops::DerefMut", "deref_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true),
|
||||
|
|
@ -3827,7 +3820,7 @@ enum SelfKind {
|
|||
Value,
|
||||
Ref,
|
||||
RefMut,
|
||||
No,
|
||||
No, // When we want the first argument type to be different than `Self`
|
||||
}
|
||||
|
||||
impl SelfKind {
|
||||
|
|
|
|||
|
|
@ -98,13 +98,12 @@ pub(super) fn check<'tcx>(
|
|||
format!(".as_ref().map({})", snippet(cx, map_arg.span, ".."))
|
||||
};
|
||||
let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" };
|
||||
let hint = format!("{}.{}()", snippet(cx, as_ref_recv.span, ".."), method_hint);
|
||||
let suggestion = format!("try using {} instead", method_hint);
|
||||
let hint = format!("{}.{method_hint}()", snippet(cx, as_ref_recv.span, ".."));
|
||||
let suggestion = format!("try using {method_hint} instead");
|
||||
|
||||
let msg = format!(
|
||||
"called `{0}` on an Option value. This can be done more directly \
|
||||
by calling `{1}` instead",
|
||||
current_method, hint
|
||||
"called `{current_method}` on an Option value. This can be done more directly \
|
||||
by calling `{hint}` instead"
|
||||
);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try using `map` instead",
|
||||
format!("{0}.map({1} {2})", self_snippet, arg_snippet,func_snippet),
|
||||
format!("{self_snippet}.map({arg_snippet} {func_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try using `and_then` instead",
|
||||
format!("{0}.and_then({1})", self_snippet, func_snippet),
|
||||
format!("{self_snippet}.and_then({func_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if f_arg_is_some {
|
||||
|
|
@ -115,7 +115,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
msg,
|
||||
"try using `ok` instead",
|
||||
format!("{0}.ok()", self_snippet),
|
||||
format!("{self_snippet}.ok()"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,9 +65,8 @@ pub(super) fn check<'tcx>(
|
|||
"map_or(<a>, <f>)"
|
||||
};
|
||||
let msg = &format!(
|
||||
"called `map(<f>).unwrap_or({})` on an `Option` value. \
|
||||
This can be done more directly by calling `{}` instead",
|
||||
arg, suggest
|
||||
"called `map(<f>).unwrap_or({arg})` on an `Option` value. \
|
||||
This can be done more directly by calling `{suggest}` instead"
|
||||
);
|
||||
|
||||
span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| {
|
||||
|
|
@ -82,10 +81,10 @@ pub(super) fn check<'tcx>(
|
|||
];
|
||||
|
||||
if !unwrap_snippet_none {
|
||||
suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{}, ", unwrap_snippet)));
|
||||
suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!("{unwrap_snippet}, ")));
|
||||
}
|
||||
|
||||
diag.multipart_suggestion(&format!("use `{}` instead", suggest), suggestion, applicability);
|
||||
diag.multipart_suggestion(&format!("use `{suggest}` instead"), suggestion, applicability);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
OR_FUN_CALL,
|
||||
method_span.with_hi(span.hi()),
|
||||
&format!("use of `{}` followed by a call to `{}`", name, path),
|
||||
&format!("use of `{name}` followed by a call to `{path}`"),
|
||||
"try this",
|
||||
format!("{}()", sugg),
|
||||
format!("{sugg}()"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ pub(super) fn check<'tcx>(
|
|||
|
||||
if use_lambda {
|
||||
let l_arg = if fn_has_arguments { "_" } else { "" };
|
||||
format!("|{}| {}", l_arg, snippet).into()
|
||||
format!("|{l_arg}| {snippet}").into()
|
||||
} else {
|
||||
snippet
|
||||
}
|
||||
|
|
@ -141,9 +141,9 @@ pub(super) fn check<'tcx>(
|
|||
cx,
|
||||
OR_FUN_CALL,
|
||||
span_replace_word,
|
||||
&format!("use of `{}` followed by a function call", name),
|
||||
&format!("use of `{name}` followed by a function call"),
|
||||
"try this",
|
||||
format!("{}_{}({})", name, suffix, sugg),
|
||||
format!("{name}_{suffix}({sugg})"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,7 @@ pub(super) fn check<'tcx>(
|
|||
let option_check_method = if is_some { "is_some" } else { "is_none" };
|
||||
// lint if caller of search is an Iterator
|
||||
if is_trait_method(cx, is_some_recv, sym::Iterator) {
|
||||
let msg = format!(
|
||||
"called `{}()` after searching an `Iterator` with `{}`",
|
||||
option_check_method, search_method
|
||||
);
|
||||
let msg = format!("called `{option_check_method}()` after searching an `Iterator` with `{search_method}`");
|
||||
let search_snippet = snippet(cx, search_arg.span, "..");
|
||||
if search_snippet.lines().count() <= 1 {
|
||||
// suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()`
|
||||
|
|
@ -86,8 +83,7 @@ pub(super) fn check<'tcx>(
|
|||
&msg,
|
||||
"use `!_.any()` instead",
|
||||
format!(
|
||||
"!{}.any({})",
|
||||
iter,
|
||||
"!{iter}.any({})",
|
||||
any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
|
||||
),
|
||||
applicability,
|
||||
|
|
@ -119,7 +115,7 @@ pub(super) fn check<'tcx>(
|
|||
if is_string_or_str_slice(search_recv);
|
||||
if is_string_or_str_slice(search_arg);
|
||||
then {
|
||||
let msg = format!("called `{}()` after calling `find()` on a string", option_check_method);
|
||||
let msg = format!("called `{option_check_method}()` after calling `find()` on a string");
|
||||
match option_check_method {
|
||||
"is_some" => {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
|
@ -130,7 +126,7 @@ pub(super) fn check<'tcx>(
|
|||
method_span.with_hi(expr.span.hi()),
|
||||
&msg,
|
||||
"use `contains()` instead",
|
||||
format!("contains({})", find_arg),
|
||||
format!("contains({find_arg})"),
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
|
|
@ -144,7 +140,7 @@ pub(super) fn check<'tcx>(
|
|||
expr.span,
|
||||
&msg,
|
||||
"use `!_.contains()` instead",
|
||||
format!("!{}.contains({})", string, find_arg),
|
||||
format!("!{string}.contains({find_arg})"),
|
||||
applicability,
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::
|
|||
let base_string_snippet =
|
||||
snippet_with_applicability(cx, receiver.span.source_callsite(), "_", &mut applicability);
|
||||
let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);
|
||||
let sugg = format!("{}.insert({}, {})", base_string_snippet, pos_arg, extension_string);
|
||||
let sugg = format!("{base_string_snippet}.insert({pos_arg}, {extension_string})");
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SINGLE_CHAR_ADD_STR,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::
|
|||
if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability) {
|
||||
let base_string_snippet =
|
||||
snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability);
|
||||
let sugg = format!("{}.push({})", base_string_snippet, extension_string);
|
||||
let sugg = format!("{base_string_snippet}.push({extension_string})");
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SINGLE_CHAR_ADD_STR,
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx
|
|||
cx,
|
||||
STABLE_SORT_PRIMITIVE,
|
||||
e.span,
|
||||
&format!("used `sort` on primitive type `{}`", slice_type),
|
||||
&format!("used `sort` on primitive type `{slice_type}`"),
|
||||
|diag| {
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let recv_snip = snippet_with_context(cx, recv.span, e.span.ctxt(), "..", &mut app).0;
|
||||
diag.span_suggestion(e.span, "try", format!("{}.sort_unstable()", recv_snip), app);
|
||||
diag.span_suggestion(e.span, "try", format!("{recv_snip}.sort_unstable()"), app);
|
||||
diag.note(
|
||||
"an unstable sort typically performs faster without any observable difference for this data type",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
|||
"calling `.extend(_.chars())`",
|
||||
"try this",
|
||||
format!(
|
||||
"{}.push_str({}{})",
|
||||
"{}.push_str({ref_str}{})",
|
||||
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
|
||||
ref_str,
|
||||
snippet_with_applicability(cx, target.span, "..", &mut applicability)
|
||||
),
|
||||
applicability,
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, se
|
|||
}
|
||||
|
||||
let (msg, note_msg) = if count == 0 {
|
||||
(format!("`{}` called with `0` splits", method_name),
|
||||
(format!("`{method_name}` called with `0` splits"),
|
||||
"the resulting iterator will always return `None`")
|
||||
} else {
|
||||
(format!("`{}` called with `1` split", method_name),
|
||||
(format!("`{method_name}` called with `1` split"),
|
||||
if self_ty.is_slice() {
|
||||
"the resulting iterator will always return the entire slice followed by `None`"
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) -
|
|||
cx,
|
||||
SUSPICIOUS_TO_OWNED,
|
||||
expr.span,
|
||||
&format!("this `to_owned` call clones the {0} itself and does not cause the {0} contents to become owned", input_type),
|
||||
&format!("this `to_owned` call clones the {input_type} itself and does not cause the {input_type} contents to become owned"),
|
||||
"consider using, depending on intent",
|
||||
format!("{0}.clone()` or `{0}.into_owned()", recv_snip),
|
||||
format!("{recv_snip}.clone()` or `{recv_snip}.into_owned()"),
|
||||
app,
|
||||
);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
|
|||
UNNECESSARY_FIND_MAP
|
||||
},
|
||||
expr.span,
|
||||
&format!("this `.{}` can be written more simply using `.{}`", name, sugg),
|
||||
&format!("this `.{name}` can be written more simply using `.{sugg}`"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,15 +49,12 @@ pub(super) fn check(
|
|||
let mut applicability = Applicability::MachineApplicable;
|
||||
let sugg = if replacement_has_args {
|
||||
format!(
|
||||
"{replacement}(|{s}| {r})",
|
||||
replacement = replacement_method_name,
|
||||
s = second_arg_ident,
|
||||
"{replacement_method_name}(|{second_arg_ident}| {r})",
|
||||
r = snippet_with_applicability(cx, right_expr.span, "EXPR", &mut applicability),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{replacement}()",
|
||||
replacement = replacement_method_name,
|
||||
"{replacement_method_name}()",
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ pub fn check_for_loop_iter(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
expr.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
|diag| {
|
||||
// If `check_into_iter_call_arg` called `check_for_loop_iter` because a call to
|
||||
// a `to_owned`-like function was removed, then the next suggestion may be
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ pub(super) fn check<'tcx>(
|
|||
span_lint_and_then(cx, UNNECESSARY_LAZY_EVALUATIONS, expr.span, msg, |diag| {
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
&format!("use `{}(..)` instead", simplify_using),
|
||||
format!("{}({})", simplify_using, snippet(cx, body_expr.span, "..")),
|
||||
&format!("use `{simplify_using}(..)` instead"),
|
||||
format!("{simplify_using}({})", snippet(cx, body_expr.span, "..")),
|
||||
applicability,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trai
|
|||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
|
||||
use rustc_hir_analysis::check::{FnCtxt, Inherited};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::Mutability;
|
||||
|
|
@ -18,7 +19,6 @@ use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitP
|
|||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
|
||||
use rustc_hir_analysis::check::{FnCtxt, Inherited};
|
||||
use std::cmp::max;
|
||||
|
||||
use super::UNNECESSARY_TO_OWNED;
|
||||
|
|
@ -132,12 +132,11 @@ fn check_addr_of_expr(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
parent.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"use",
|
||||
format!(
|
||||
"{:&>width$}{}",
|
||||
"{:&>width$}{receiver_snippet}",
|
||||
"",
|
||||
receiver_snippet,
|
||||
width = n_target_refs - n_receiver_refs
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
|
|
@ -154,7 +153,7 @@ fn check_addr_of_expr(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
parent.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"use",
|
||||
receiver_snippet,
|
||||
Applicability::MachineApplicable,
|
||||
|
|
@ -164,7 +163,7 @@ fn check_addr_of_expr(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
expr.span.with_lo(receiver.span.hi()),
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"remove this",
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
|
|
@ -181,9 +180,9 @@ fn check_addr_of_expr(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
parent.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"use",
|
||||
format!("{}.as_ref()", receiver_snippet),
|
||||
format!("{receiver_snippet}.as_ref()"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return true;
|
||||
|
|
@ -228,9 +227,9 @@ fn check_into_iter_call_arg(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
parent.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"use",
|
||||
format!("{}.iter().{}()", receiver_snippet, cloned_or_copied),
|
||||
format!("{receiver_snippet}.iter().{cloned_or_copied}()"),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return true;
|
||||
|
|
@ -275,9 +274,9 @@ fn check_other_call_arg<'tcx>(
|
|||
cx,
|
||||
UNNECESSARY_TO_OWNED,
|
||||
maybe_arg.span,
|
||||
&format!("unnecessary use of `{}`", method_name),
|
||||
&format!("unnecessary use of `{method_name}`"),
|
||||
"use",
|
||||
format!("{:&>width$}{}", "", receiver_snippet, width = n_refs),
|
||||
format!("{:&>n_refs$}{receiver_snippet}", ""),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
|
|||
cx,
|
||||
USELESS_ASREF,
|
||||
expr.span,
|
||||
&format!("this call to `{}` does nothing", call_name),
|
||||
&format!("this call to `{call_name}` does nothing"),
|
||||
"try this",
|
||||
snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(),
|
||||
applicability,
|
||||
|
|
|
|||
|
|
@ -61,20 +61,20 @@ impl Convention {
|
|||
impl fmt::Display for Convention {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match *self {
|
||||
Self::Eq(this) => format!("`{}`", this).fmt(f),
|
||||
Self::StartsWith(this) => format!("`{}*`", this).fmt(f),
|
||||
Self::EndsWith(this) => format!("`*{}`", this).fmt(f),
|
||||
Self::NotEndsWith(this) => format!("`~{}`", this).fmt(f),
|
||||
Self::Eq(this) => format!("`{this}`").fmt(f),
|
||||
Self::StartsWith(this) => format!("`{this}*`").fmt(f),
|
||||
Self::EndsWith(this) => format!("`*{this}`").fmt(f),
|
||||
Self::NotEndsWith(this) => format!("`~{this}`").fmt(f),
|
||||
Self::IsSelfTypeCopy(is_true) => {
|
||||
format!("`self` type is{} `Copy`", if is_true { "" } else { " not" }).fmt(f)
|
||||
},
|
||||
Self::ImplementsTrait(is_true) => {
|
||||
let (negation, s_suffix) = if is_true { ("", "s") } else { (" does not", "") };
|
||||
format!("method{} implement{} a trait", negation, s_suffix).fmt(f)
|
||||
format!("method{negation} implement{s_suffix} a trait").fmt(f)
|
||||
},
|
||||
Self::IsTraitItem(is_true) => {
|
||||
let suffix = if is_true { " is" } else { " is not" };
|
||||
format!("method{} a trait item", suffix).fmt(f)
|
||||
format!("method{suffix} a trait item").fmt(f)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -138,8 +138,7 @@ pub(super) fn check<'tcx>(
|
|||
WRONG_SELF_CONVENTION,
|
||||
first_arg_span,
|
||||
&format!(
|
||||
"{} usually take {}",
|
||||
suggestion,
|
||||
"{suggestion} usually take {}",
|
||||
&self_kinds
|
||||
.iter()
|
||||
.map(|k| k.description())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue