Merge remote-tracking branch 'upstream/master' into rustup

This commit is contained in:
Philipp Krones 2022-09-28 14:27:32 +02:00
commit bbcde66685
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
323 changed files with 3669 additions and 1716 deletions

View file

@ -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,

View file

@ -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({})",

View file

@ -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,
);

View file

@ -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,
);

View file

@ -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,

View file

@ -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
);
}

View file

@ -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,
);
}

View file

@ -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);
}

View file

@ -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 {

View file

@ -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 {

View file

@ -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("::"))
}
}
}

View file

@ -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,
);
}

View file

@ -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,
);

View file

@ -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,
);

View file

@ -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,
);
},

View file

@ -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(),

View file

@ -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,
);

View file

@ -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,

View file

@ -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()",

View file

@ -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,
);

View file

@ -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,

View file

@ -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"),
);
}

View file

@ -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,

View file

@ -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,
);

View file

@ -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,

View file

@ -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
)
}

View file

@ -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,
);

View file

@ -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,
);
}

View file

@ -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,
)

View file

@ -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;

View file

@ -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 {

View file

@ -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,

View file

@ -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,
);
}

View file

@ -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);
});
}
}

View file

@ -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,
);
}

View file

@ -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,
);
},

View file

@ -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,

View file

@ -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,

View file

@ -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",
);

View file

@ -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,

View file

@ -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 {

View file

@ -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;

View file

@ -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}`"),
);
}
}

View file

@ -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}()",
)
};

View file

@ -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

View file

@ -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,
);
});

View file

@ -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;

View file

@ -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,

View file

@ -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())