Auto merge of #13278 - Alexendoo:misc-cleanup, r=y21

Misc cleanup

changelog: none
This commit is contained in:
bors 2024-08-19 17:42:25 +00:00
commit ba6bc81277
44 changed files with 89 additions and 245 deletions

View File

@ -1,5 +1,3 @@
//! checks for attributes
mod allow_attributes; mod allow_attributes;
mod allow_attributes_without_reason; mod allow_attributes_without_reason;
mod blanket_clippy_restriction_lints; mod blanket_clippy_restriction_lints;

View File

@ -1,5 +1,3 @@
//! lint on missing cargo common metadata
use cargo_metadata::Metadata; use cargo_metadata::Metadata;
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_lint::LateContext; use rustc_lint::LateContext;

View File

@ -1,5 +1,3 @@
//! lint on multiple versions of a crate being used
use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId}; use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use itertools::Itertools; use itertools::Itertools;

View File

@ -4,7 +4,7 @@
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize}; use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
use rustc_errors::{Applicability, Diag, SuggestionStyle}; use rustc_errors::{Applicability, Diag};
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -190,12 +190,10 @@ fn offer_suggestion(
format!("{cast_to_snip}::try_from({})", Sugg::hir(cx, cast_expr, "..")) format!("{cast_to_snip}::try_from({})", Sugg::hir(cx, cast_expr, ".."))
}; };
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
expr.span, expr.span,
"... or use `try_from` and handle the error accordingly", "... or use `try_from` and handle the error accordingly",
suggestion, suggestion,
Applicability::Unspecified, Applicability::Unspecified,
// always show the suggestion in a separate line
SuggestionStyle::ShowAlways,
); );
} }

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_hir::Expr; use rustc_hir::Expr;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
@ -24,12 +24,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
expr.span, expr.span,
format!("casting function pointer `{from_snippet}` to `{cast_to}`"), format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
|diag| { |diag| {
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
expr.span, expr.span,
"did you mean to invoke the function?", "did you mean to invoke the function?",
format!("{from_snippet}() as {cast_to}"), format!("{from_snippet}() as {cast_to}"),
applicability, applicability,
SuggestionStyle::ShowAlways,
); );
}, },
); );

View File

@ -1,5 +1,3 @@
//! lint on manually implemented checked conversions that could be transformed into `try_from`
use clippy_config::msrvs::{self, Msrv}; use clippy_config::msrvs::{self, Msrv};
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;

View File

@ -1,5 +1,3 @@
//! calculate cognitive complexity and warn about overly complex functions
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::source::{IntoSpan, SpanRangeExt};

View File

@ -1,17 +1,3 @@
//! Checks for if expressions that contain only an if expression.
//!
//! For example, the lint would catch:
//!
//! ```rust,ignore
//! if x {
//! if y {
//! println!("Hello world");
//! }
//! }
//! ```
//!
//! This lint is **warn** by default
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet, snippet_block, snippet_block_with_applicability}; use clippy_utils::source::{snippet, snippet_block, snippet_block_with_applicability};
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;

View File

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
use clippy_utils::visitors::{for_each_expr, Visitable}; use clippy_utils::visitors::{for_each_expr, Visitable};
use clippy_utils::{get_enclosing_block, path_to_local_id}; use clippy_utils::{get_enclosing_block, path_to_local_id};
use core::ops::ControlFlow; use core::ops::ControlFlow;
@ -7,7 +7,6 @@
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -44,24 +43,11 @@
} }
declare_lint_pass!(CollectionIsNeverRead => [COLLECTION_IS_NEVER_READ]); declare_lint_pass!(CollectionIsNeverRead => [COLLECTION_IS_NEVER_READ]);
// Add `String` here when it is added to diagnostic items
static COLLECTIONS: [Symbol; 9] = [
sym::BTreeMap,
sym::BTreeSet,
sym::BinaryHeap,
sym::HashMap,
sym::HashSet,
sym::LinkedList,
sym::Option,
sym::Vec,
sym::VecDeque,
];
impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead { impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
// Look for local variables whose type is a container. Search surrounding block for read access. // Look for local variables whose type is a container. Search surrounding block for read access.
if let PatKind::Binding(_, local_id, _, _) = local.pat.kind if let PatKind::Binding(_, local_id, _, _) = local.pat.kind
&& match_acceptable_type(cx, local, &COLLECTIONS) && match_acceptable_type(cx, local)
&& let Some(enclosing_block) = get_enclosing_block(cx, local.hir_id) && let Some(enclosing_block) = get_enclosing_block(cx, local.hir_id)
&& has_no_read_access(cx, local_id, enclosing_block) && has_no_read_access(cx, local_id, enclosing_block)
{ {
@ -70,11 +56,22 @@ fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
} }
} }
fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[Symbol]) -> bool { fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
let ty = cx.typeck_results().pat_ty(local.pat); let ty = cx.typeck_results().pat_ty(local.pat);
collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym)) matches!(
// String type is a lang item but not a diagnostic item for now so we need a separate check get_type_diagnostic_name(cx, ty),
|| is_type_lang_item(cx, ty, LangItem::String) Some(
sym::BTreeMap
| sym::BTreeSet
| sym::BinaryHeap
| sym::HashMap
| sym::HashSet
| sym::LinkedList
| sym::Option
| sym::Vec
| sym::VecDeque
)
) || is_type_lang_item(cx, ty, LangItem::String)
} }
fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool { fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool {

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -46,7 +46,7 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
"calling `std::fs::create_dir` where there may be a better way", "calling `std::fs::create_dir` where there may be a better way",
|diag| { |diag| {
let mut app = Applicability::MaybeIncorrect; let mut app = Applicability::MaybeIncorrect;
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
expr.span, expr.span,
"consider calling `std::fs::create_dir_all` instead", "consider calling `std::fs::create_dir_all` instead",
format!( format!(
@ -54,7 +54,6 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
snippet_with_applicability(cx, arg.span, "..", &mut app) snippet_with_applicability(cx, arg.span, "..", &mut app)
), ),
app, app,
SuggestionStyle::ShowAlways,
); );
}, },
); );

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use itertools::Itertools; use itertools::Itertools;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::{BytePos, Span}; use rustc_span::{BytePos, Span};
use std::ops::Range; use std::ops::Range;
@ -59,12 +59,11 @@ pub(super) fn check(
&& (doc_comment == "///" || doc_comment == "//!") && (doc_comment == "///" || doc_comment == "//!")
{ {
// suggest filling in a blank line // suggest filling in a blank line
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
line_break_span.shrink_to_lo(), line_break_span.shrink_to_lo(),
"if this should be its own paragraph, add a blank doc comment line", "if this should be its own paragraph, add a blank doc comment line",
format!("\n{doc_comment}"), format!("\n{doc_comment}"),
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
SuggestionStyle::ShowAlways,
); );
if ccount > 0 || blockquote_level > 0 { if ccount > 0 || blockquote_level > 0 {
diag.help("if this not intended to be a quote at all, escape it with `\\>`"); diag.help("if this not intended to be a quote at all, escape it with `\\>`");
@ -79,12 +78,11 @@ pub(super) fn check(
if ccount == 0 && blockquote_level == 0 { if ccount == 0 && blockquote_level == 0 {
// simpler suggestion style for indentation // simpler suggestion style for indentation
let indent = list_indentation - lcount; let indent = list_indentation - lcount;
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
span.shrink_to_hi(), span.shrink_to_hi(),
"indent this line", "indent this line",
std::iter::repeat(" ").take(indent).join(""), std::iter::repeat(" ").take(indent).join(""),
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
SuggestionStyle::ShowAlways,
); );
diag.help("if this is supposed to be its own paragraph, add a blank line"); diag.help("if this is supposed to be its own paragraph, add a blank line");
return; return;
@ -107,12 +105,11 @@ pub(super) fn check(
suggested.push_str(text); suggested.push_str(text);
} }
} }
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
span, span,
"add markers to start of line", "add markers to start of line",
suggested, suggested,
Applicability::MachineApplicable, Applicability::MachineApplicable,
SuggestionStyle::ShowAlways,
); );
diag.help("if this not intended to be a quote at all, escape it with `\\>`"); diag.help("if this not intended to be a quote at all, escape it with `\\>`");
}); });

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::{BytePos, Pos, Span}; use rustc_span::{BytePos, Pos, Span};
use url::Url; use url::Url;
@ -137,24 +137,15 @@ fn has_hyphen(s: &str) -> bool {
} }
if has_underscore(word) || word.contains("::") || is_camel_case(word) || word.ends_with("()") { if has_underscore(word) || word.contains("::") || is_camel_case(word) || word.ends_with("()") {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_then( span_lint_and_then(
cx, cx,
DOC_MARKDOWN, DOC_MARKDOWN,
span, span,
"item in documentation is missing backticks", "item in documentation is missing backticks",
|diag| { |diag| {
let mut applicability = Applicability::MachineApplicable;
let snippet = snippet_with_applicability(cx, span, "..", &mut applicability); let snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
diag.span_suggestion_with_style( diag.span_suggestion_verbose(span, "try", format!("`{snippet}`"), applicability);
span,
"try",
format!("`{snippet}`"),
applicability,
// always show the suggestion in a separate line, since the
// inline presentation adds another pair of backticks
SuggestionStyle::ShowAlways,
);
}, },
); );
} }

View File

@ -1,5 +1,3 @@
//! Lint on if expressions with an else if, but without a final else branch.
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use rustc_ast::ast::{Expr, ExprKind}; use rustc_ast::ast::{Expr, ExprKind};
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};

View File

@ -1,5 +1,3 @@
//! lint when there is an enum with no variants
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,6 +1,3 @@
//! lint on C-like enums that are `repr(isize/usize)` and have values that
//! don't fit into an `i32`
use clippy_utils::consts::{mir_to_const, Constant}; use clippy_utils::consts::{mir_to_const, Constant};
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use rustc_hir::{Item, ItemKind}; use rustc_hir::{Item, ItemKind};

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::higher::VecArgs; use clippy_utils::higher::VecArgs;
use clippy_utils::source::snippet_opt; use clippy_utils::source::snippet_opt;
use clippy_utils::ty::type_diagnostic_name; use clippy_utils::ty::get_type_diagnostic_name;
use clippy_utils::usage::{local_used_after_expr, local_used_in}; use clippy_utils::usage::{local_used_after_expr, local_used_in};
use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id}; use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id};
use rustc_errors::Applicability; use rustc_errors::Applicability;
@ -139,7 +139,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
{ {
let callee_ty_raw = typeck.expr_ty(callee); let callee_ty_raw = typeck.expr_ty(callee);
let callee_ty = callee_ty_raw.peel_refs(); let callee_ty = callee_ty_raw.peel_refs();
if matches!(type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc)) if matches!(get_type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc))
|| !check_inputs(typeck, body.params, None, args) || !check_inputs(typeck, body.params, None, args)
{ {
return; return;

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::numeric_literal; use clippy_utils::numeric_literal;
use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_ast::ast::{self, LitFloatType, LitKind};
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, FloatTy}; use rustc_middle::ty::{self, FloatTy};
@ -117,12 +117,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if type_suffix.is_none() { if type_suffix.is_none() {
float_str.push_str(".0"); float_str.push_str(".0");
} }
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
expr.span, expr.span,
"consider changing the type or replacing it with", "consider changing the type or replacing it with",
numeric_literal::format(&float_str, type_suffix, true), numeric_literal::format(&float_str, type_suffix, true),
Applicability::MachineApplicable, Applicability::MachineApplicable,
SuggestionStyle::ShowAlways,
); );
}, },
); );
@ -134,12 +133,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
expr.span, expr.span,
"float has excessive precision", "float has excessive precision",
|diag| { |diag| {
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
expr.span, expr.span,
"consider changing the type or truncating it to", "consider changing the type or truncating it to",
numeric_literal::format(&float_str, type_suffix, true), numeric_literal::format(&float_str, type_suffix, true),
Applicability::MachineApplicable, Applicability::MachineApplicable,
SuggestionStyle::ShowAlways,
); );
}, },
); );

View File

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_in_test; use clippy_utils::is_in_test;
use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind}; use rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind};
@ -18,20 +19,18 @@ fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_
|diag| { |diag| {
if let Some(gen_span) = generics.span_for_param_suggestion() { if let Some(gen_span) = generics.span_for_param_suggestion() {
// If there's already a generic param with the same bound, do not lint **this** suggestion. // If there's already a generic param with the same bound, do not lint **this** suggestion.
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
gen_span, gen_span,
"add a type parameter", "add a type parameter",
format!(", {{ /* Generic name */ }}: {}", &param.name.ident().as_str()[5..]), format!(", {{ /* Generic name */ }}: {}", &param.name.ident().as_str()[5..]),
rustc_errors::Applicability::HasPlaceholders, Applicability::HasPlaceholders,
rustc_errors::SuggestionStyle::ShowAlways,
); );
} else { } else {
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
generics.span, generics.span,
"add a type parameter", "add a type parameter",
format!("<{{ /* Generic name */ }}: {}>", &param.name.ident().as_str()[5..]), format!("<{{ /* Generic name */ }}: {}>", &param.name.ident().as_str()[5..]),
rustc_errors::Applicability::HasPlaceholders, Applicability::HasPlaceholders,
rustc_errors::SuggestionStyle::ShowAlways,
); );
} }
}, },

View File

@ -8,7 +8,7 @@
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span};
use clippy_utils::attrs::is_proc_macro; use clippy_utils::attrs::is_proc_macro;
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
@ -193,17 +193,13 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
} }
} }
static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc];
fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool { fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {
match *ty.kind() { match *ty.kind() {
// primitive types are never mutable // primitive types are never mutable
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false, ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
ty::Adt(adt, args) => { ty::Adt(adt, args) => {
tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env) tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env)
|| KNOWN_WRAPPER_TYS || matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::Rc | sym::Arc))
.iter()
.any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
&& args.types().any(|ty| is_mutable_ty(cx, ty, tys)) && args.types().any(|ty| is_mutable_ty(cx, ty, tys))
}, },
ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)), ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),

View File

@ -1,6 +1,3 @@
//! lint on if branches that could be swapped so no `!` operation is necessary
//! on the condition
use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_else_clause; use clippy_utils::is_else_clause;

View File

@ -3,7 +3,7 @@
use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{get_async_fn_body, is_async_fn, is_from_proc_macro}; use clippy_utils::{get_async_fn_body, is_async_fn, is_from_proc_macro};
use core::ops::ControlFlow; use core::ops::ControlFlow;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId}; use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -54,13 +54,7 @@ fn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {
|diag| { |diag| {
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;
let snip = snippet_with_applicability(cx, span, "..", &mut app); let snip = snippet_with_applicability(cx, span, "..", &mut app);
diag.span_suggestion_with_style( diag.span_suggestion_verbose(span, "add `return` as shown", format!("return {snip}"), app);
span,
"add `return` as shown",
format!("return {snip}"),
app,
SuggestionStyle::ShowAlways,
);
}, },
); );
} }
@ -75,12 +69,11 @@ fn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, exp
|diag| { |diag| {
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0; let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0;
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
break_span, break_span,
"change `break` to `return` as shown", "change `break` to `return` as shown",
format!("return {snip}"), format!("return {snip}"),
app, app,
SuggestionStyle::ShowAlways,
); );
}, },
); );

View File

@ -1,5 +1,3 @@
//! lint on indexing and slicing operations
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint, span_lint_and_then};

View File

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::higher; use clippy_utils::higher;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
use rustc_hir::{BorrowKind, Closure, Expr, ExprKind}; use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::sym;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -210,18 +210,6 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
("product", 0), ("product", 0),
]; ];
/// the paths of types that are known to be infinitely allocating
const INFINITE_COLLECTORS: &[Symbol] = &[
sym::BinaryHeap,
sym::BTreeMap,
sym::BTreeSet,
sym::HashMap,
sym::HashSet,
sym::LinkedList,
sym::Vec,
sym::VecDeque,
];
fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
match expr.kind { match expr.kind {
ExprKind::MethodCall(method, receiver, args, _) => { ExprKind::MethodCall(method, receiver, args, _) => {
@ -248,10 +236,19 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
} }
} else if method.ident.name == sym!(collect) { } else if method.ident.name == sym!(collect) {
let ty = cx.typeck_results().expr_ty(expr); let ty = cx.typeck_results().expr_ty(expr);
if INFINITE_COLLECTORS if matches!(
.iter() get_type_diagnostic_name(cx, ty),
.any(|diag_item| is_type_diagnostic_item(cx, ty, *diag_item)) Some(
{ sym::BinaryHeap
| sym::BTreeMap
| sym::BTreeSet
| sym::HashMap
| sym::HashSet
| sym::LinkedList
| sym::Vec
| sym::VecDeque,
)
) {
return is_infinite(cx, receiver); return is_infinite(cx, receiver);
} }
} }

View File

@ -1,5 +1,3 @@
//! lint on inherent implementations
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_lint_allowed; use clippy_utils::is_lint_allowed;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;

View File

@ -1,5 +1,3 @@
//! checks for `#[inline]` on trait methods without bodies
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sugg::DiagExt; use clippy_utils::sugg::DiagExt;
use rustc_errors::Applicability; use rustc_errors::Applicability;

View File

@ -1,5 +1,3 @@
//! lint on blocks unnecessarily using >= with a + 1 or - 1
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt; use clippy_utils::source::snippet_opt;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind}; use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};

View File

@ -1,5 +1,3 @@
//! lint on enum variants that are prefixed or suffixed by the same characters
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir}; use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
use clippy_utils::is_bool; use clippy_utils::is_bool;

View File

@ -1,5 +1,3 @@
//! lint when items are used after statements
use clippy_utils::diagnostics::span_lint_hir; use clippy_utils::diagnostics::span_lint_hir;
use rustc_hir::{Block, ItemKind, StmtKind}; use rustc_hir::{Block, ItemKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};

View File

@ -1,5 +1,3 @@
//! lint when there is a large size difference between variants on an enum
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;

View File

@ -3,7 +3,7 @@
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::{get_parent_expr, is_from_proc_macro}; use clippy_utils::{get_parent_expr, is_from_proc_macro};
use hir::def_id::DefId; use hir::def_id::DefId;
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind}; use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -143,12 +143,11 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc
&& !is_from_proc_macro(cx, expr) && !is_from_proc_macro(cx, expr)
{ {
span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| { span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
span, span,
"use the associated constant instead", "use the associated constant instead",
sugg, sugg,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
SuggestionStyle::ShowAlways,
); );
}); });
} }

View File

@ -1,6 +1,3 @@
//! Lints concerned with the grouping of digits with underscores in integral or
//! floating-point literal expressions.
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::numeric_literal::{NumericLiteral, Radix}; use clippy_utils::numeric_literal::{NumericLiteral, Radix};

View File

@ -2,14 +2,14 @@
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
use clippy_utils::{match_def_path, paths, SpanlessEq}; use clippy_utils::{match_def_path, paths, SpanlessEq};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::ExprKind::Assign; use rustc_hir::ExprKind::Assign;
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{impl_lint_pass, RustcVersion}; use rustc_session::impl_lint_pass;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::Span;
@ -20,16 +20,6 @@
&paths::SLICE_INTO, &paths::SLICE_INTO,
&paths::VEC_DEQUE_ITER, &paths::VEC_DEQUE_ITER,
]; ];
const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
(sym::BinaryHeap, Some(msrvs::BINARY_HEAP_RETAIN)),
(sym::BTreeSet, Some(msrvs::BTREE_SET_RETAIN)),
(sym::BTreeMap, Some(msrvs::BTREE_MAP_RETAIN)),
(sym::HashSet, Some(msrvs::HASH_SET_RETAIN)),
(sym::HashMap, Some(msrvs::HASH_MAP_RETAIN)),
(sym::Vec, None),
(sym::VecDeque, None),
];
const MAP_TYPES: [rustc_span::Symbol; 2] = [sym::BTreeMap, sym::HashMap];
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -264,16 +254,22 @@ fn match_acceptable_def_path(cx: &LateContext<'_>, collect_def_id: DefId) -> boo
} }
fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool { fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs(); let ty = cx.typeck_results().expr_ty(expr).peel_refs();
ACCEPTABLE_TYPES.iter().any(|(ty, acceptable_msrv)| { let required = match get_type_diagnostic_name(cx, ty) {
is_type_diagnostic_item(cx, expr_ty, *ty) Some(sym::BinaryHeap) => msrvs::BINARY_HEAP_RETAIN,
&& acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv)) Some(sym::BTreeSet) => msrvs::BTREE_SET_RETAIN,
}) Some(sym::BTreeMap) => msrvs::BTREE_MAP_RETAIN,
Some(sym::HashSet) => msrvs::HASH_SET_RETAIN,
Some(sym::HashMap) => msrvs::HASH_MAP_RETAIN,
Some(sym::Vec | sym::VecDeque) => return true,
_ => return false,
};
msrv.meets(required)
} }
fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs(); let ty = cx.typeck_results().expr_ty(expr).peel_refs();
MAP_TYPES.iter().any(|ty| is_type_diagnostic_item(cx, expr_ty, *ty)) matches!(get_type_diagnostic_name(cx, ty), Some(sym::BTreeMap | sym::HashMap))
} }
fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) { fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {

View File

@ -74,7 +74,7 @@ pub(super) fn check<'tcx>(
"&" "&"
}; };
diag.span_suggestion_with_style( diag.span_suggestion_verbose(
span, span,
"using `[]` is clearer and more concise", "using `[]` is clearer and more concise",
format!( format!(
@ -82,7 +82,6 @@ pub(super) fn check<'tcx>(
snippet_with_applicability(cx, recv.span, "..", &mut applicability) snippet_with_applicability(cx, recv.span, "..", &mut applicability)
), ),
applicability, applicability,
rustc_errors::SuggestionStyle::ShowAlways,
); );
}, },
); );

View File

@ -1,5 +1,3 @@
//! Lint for `c.is_digit(10)`
use super::IS_DIGIT_ASCII_RADIX; use super::IS_DIGIT_ASCII_RADIX;
use clippy_config::msrvs::{self, Msrv}; use clippy_config::msrvs::{self, Msrv};
use clippy_utils::consts::{ConstEvalCtxt, FullInt}; use clippy_utils::consts::{ConstEvalCtxt, FullInt};

View File

@ -2,7 +2,7 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{is_type_diagnostic_item, make_normalized_projection, make_projection}; use clippy_utils::ty::{get_type_diagnostic_name, make_normalized_projection, make_projection};
use clippy_utils::{ use clippy_utils::{
can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local, path_to_local_id, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local, path_to_local_id,
CaptureKind, CaptureKind,
@ -88,9 +88,10 @@ pub(super) fn check<'tcx>(
Node::LetStmt(l) => { Node::LetStmt(l) => {
if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind
&& let ty = cx.typeck_results().expr_ty(collect_expr) && let ty = cx.typeck_results().expr_ty(collect_expr)
&& [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList] && matches!(
.into_iter() get_type_diagnostic_name(cx, ty),
.any(|item| is_type_diagnostic_item(cx, ty, item)) Some(sym::Vec | sym::VecDeque | sym::BinaryHeap | sym::LinkedList)
)
&& let iter_ty = cx.typeck_results().expr_ty(iter_expr) && let iter_ty = cx.typeck_results().expr_ty(iter_expr)
&& let Some(block) = get_enclosing_block(cx, l.hir_id) && let Some(block) = get_enclosing_block(cx, l.hir_id)
&& let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty)) && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty))

View File

@ -125,14 +125,12 @@ fn check_sig(&mut self, cx: &LateContext<'tcx>, fn_def_id: LocalDefId, decl: &hi
// generics (because the compiler cannot ensure immutability for unknown types). // generics (because the compiler cannot ensure immutability for unknown types).
fn check_ty_(&mut self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { fn check_ty_(&mut self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
let ty = ty.peel_refs(); let ty = ty.peel_refs();
if let ty::Adt(def, args) = ty.kind() { if let ty::Adt(def, args) = ty.kind()
let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] && matches!(
.iter() cx.tcx.get_diagnostic_name(def.did()),
.any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); Some(sym::HashMap | sym::BTreeMap | sym::HashSet | sym::BTreeSet)
if !is_keyed_type { )
return; {
}
let subst_ty = args.type_at(0); let subst_ty = args.type_at(0);
if self.interior_mut.is_interior_mut_ty(cx, subst_ty) { if self.interior_mut.is_interior_mut_ty(cx, subst_ty) {
span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type"); span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");

View File

@ -1,7 +1,3 @@
//! Checks for usage of mutex where an atomic value could be used
//!
//! This lint is **allow** by default
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use rustc_hir::Expr; use rustc_hir::Expr;

View File

@ -1,7 +1,3 @@
//! Checks for needless boolean results of if-else expressions
//!
//! This lint is **warn** by default
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;

View File

@ -1,38 +1,3 @@
//! Checks for continue statements in loops that are redundant.
//!
//! For example, the lint would catch
//!
//! ```rust
//! let mut a = 1;
//! let x = true;
//!
//! while a < 5 {
//! a = 6;
//! if x {
//! // ...
//! } else {
//! continue;
//! }
//! println!("Hello, world");
//! }
//! ```
//!
//! And suggest something like this:
//!
//! ```rust
//! let mut a = 1;
//! let x = true;
//!
//! while a < 5 {
//! a = 6;
//! if x {
//! // ...
//! println!("Hello, world");
//! }
//! }
//! ```
//!
//! This lint is **warn** by default.
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::{indent_of, snippet, snippet_block}; use clippy_utils::source::{indent_of, snippet, snippet_block};
use rustc_ast::ast; use rustc_ast::ast;

View File

@ -1,7 +1,3 @@
//! Checks for usage of const which the type is not `Freeze` (`Cell`-free).
//!
//! This lint is **warn** by default.
use std::ptr; use std::ptr;
use clippy_config::Conf; use clippy_config::Conf;

View File

@ -1,5 +1,3 @@
//! Checks for usage of `&Vec[_]` and `&String`.
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
use clippy_utils::source::SpanRangeExt; use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::expr_sig; use clippy_utils::ty::expr_sig;

View File

@ -1,6 +1,3 @@
//! Lint on use of `size_of` or `size_of_val` of T in an expression
//! expecting a count of T
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};

View File

@ -1,6 +1,3 @@
//! A group of attributes that can be attached to Rust code in order
//! to generate a clippy lint detecting said code automatically.
use clippy_utils::{get_attr, higher}; use clippy_utils::{get_attr, higher};
use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_ast::ast::{LitFloatType, LitKind};
use rustc_ast::LitIntType; use rustc_ast::LitIntType;

View File

@ -455,11 +455,6 @@ pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: LangItem)
} }
} }
/// Gets the diagnostic name of the type, if it has one
pub fn type_diagnostic_name(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Symbol> {
ty.ty_adt_def().and_then(|adt| cx.tcx.get_diagnostic_name(adt.did()))
}
/// Return `true` if the passed `typ` is `isize` or `usize`. /// Return `true` if the passed `typ` is `isize` or `usize`.
pub fn is_isize_or_usize(typ: Ty<'_>) -> bool { pub fn is_isize_or_usize(typ: Ty<'_>) -> bool {
matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize)) matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))