Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions clippy_lints/src/loops/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,15 @@ fn is_conditional(expr: &Expr<'_>) -> bool {

/// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the
/// actual `Iterator` that the loop uses.
pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String {
pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applicability: &mut Applicability) -> String {
let impls_iterator = cx
.tcx
.get_diagnostic_item(sym::Iterator)
.is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[]));
if impls_iterator {
format!(
"{}",
sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_paren()
sugg::Sugg::hir_with_applicability(cx, arg, "_", applicability).maybe_paren()
)
} else {
// (&x).into_iter() ==> x.iter()
Expand All @@ -281,12 +281,12 @@ pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic
};
format!(
"{}.{method_name}()",
sugg::Sugg::hir_with_applicability(cx, caller, "_", applic_ref).maybe_paren(),
sugg::Sugg::hir_with_applicability(cx, caller, "_", applicability).maybe_paren(),
)
},
_ => format!(
"{}.into_iter()",
sugg::Sugg::hir_with_applicability(cx, arg, "_", applic_ref).maybe_paren()
sugg::Sugg::hir_with_applicability(cx, arg, "_", applicability).maybe_paren()
),
}
}
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/methods/iter_skip_next.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::ITER_SKIP_NEXT;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
// lint if caller of skip is an Iterator
if is_trait_method(cx, expr, sym::Iterator) {
let mut application = Applicability::MachineApplicable;
let mut applicability = Applicability::MachineApplicable;
span_lint_and_then(
cx,
ITER_SKIP_NEXT,
Expand All @@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
&& let PatKind::Binding(ann, _, _, _) = pat.kind
&& ann != BindingMode::MUT
{
application = Applicability::Unspecified;
applicability = Applicability::Unspecified;
diag.span_help(
pat.span,
format!("for this change `{}` has to be mutable", snippet(cx, pat.span, "..")),
Expand All @@ -35,7 +35,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
expr.span.trim_start(recv.span).unwrap(),
"use `nth` instead",
format!(".nth({})", snippet(cx, arg.span, "..")),
application,
applicability,
);
},
);
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/non_std_lazy_statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl LazyInfo {
fn lint(&self, cx: &LateContext<'_>, sugg_map: &FxIndexMap<DefId, Option<String>>) {
// Applicability might get adjusted to `Unspecified` later if any calls
// in `calls_span_and_id` are not replaceable judging by the `sugg_map`.
let mut appl = Applicability::MachineApplicable;
let mut app = Applicability::MachineApplicable;
let mut suggs = vec![(self.ty_span_no_args, "std::sync::LazyLock".to_string())];

for (span, def_id) in &self.calls_span_and_id {
Expand All @@ -228,7 +228,7 @@ impl LazyInfo {
suggs.push((*span, sugg));
} else {
// If NO suggested replacement, not machine applicable
appl = Applicability::Unspecified;
app = Applicability::Unspecified;
}
}

Expand All @@ -239,7 +239,7 @@ impl LazyInfo {
self.ty_span_no_args,
"this type has been superseded by `LazyLock` in the standard library",
|diag| {
diag.multipart_suggestion("use `std::sync::LazyLock` instead", suggs, appl);
diag.multipart_suggestion("use `std::sync::LazyLock` instead", suggs, app);
},
);
}
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/significant_drop_tightening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
}
},
hir::StmtKind::Semi(semi_expr) => {
if has_drop(semi_expr, apa.first_bind_ident, self.cx) {
if has_drop(self.cx, semi_expr, apa.first_bind_ident) {
apa.has_expensive_expr_after_last_attr = false;
apa.last_stmt_span = DUMMY_SP;
return;
Expand Down Expand Up @@ -416,11 +416,11 @@ fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> {
}
}

fn has_drop(expr: &hir::Expr<'_>, first_bind_ident: Option<Ident>, lcx: &LateContext<'_>) -> bool {
fn has_drop(cx: &LateContext<'_>, expr: &hir::Expr<'_>, first_bind_ident: Option<Ident>) -> bool {
if let hir::ExprKind::Call(fun, [first_arg]) = expr.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind
&& let Res::Def(DefKind::Fn, did) = fun_path.res
&& lcx.tcx.is_diagnostic_item(sym::mem_drop, did)
&& cx.tcx.is_diagnostic_item(sym::mem_drop, did)
{
let has_ident = |local_expr: &hir::Expr<'_>| {
if let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &local_expr.kind
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/single_char_lifetime_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ declare_clippy_lint! {
declare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);

impl EarlyLintPass for SingleCharLifetimeNames {
fn check_generic_param(&mut self, ctx: &EarlyContext<'_>, param: &GenericParam) {
if param.ident.span.in_external_macro(ctx.sess().source_map()) {
fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &GenericParam) {
if param.ident.span.in_external_macro(cx.sess().source_map()) {
return;
}

Expand All @@ -51,7 +51,7 @@ impl EarlyLintPass for SingleCharLifetimeNames {
{
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
span_lint_and_then(
ctx,
cx,
SINGLE_CHAR_LIFETIME_NAMES,
param.ident.span,
"single-character lifetime names are likely uninformative",
Expand Down
1 change: 1 addition & 0 deletions clippy_lints_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2024"
[dependencies]
clippy_config = { path = "../clippy_config" }
clippy_utils = { path = "../clippy_utils" }
itertools = "0.12"
regex = { version = "1.5" }
rustc-semver = "1.1"

Expand Down
5 changes: 5 additions & 0 deletions clippy_lints_internal/src/internal_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ use clippy_utils::paths::{PathLookup, PathNS};
use clippy_utils::{sym, type_path, value_path};

// Paths inside rustc
pub static APPLICABILITY: PathLookup = type_path!(rustc_errors::Applicability);
pub static EARLY_CONTEXT: PathLookup = type_path!(rustc_lint::EarlyContext);
pub static EARLY_LINT_PASS: PathLookup = type_path!(rustc_lint::passes::EarlyLintPass);
pub static KW_MODULE: PathLookup = type_path!(rustc_span::symbol::kw);
pub static LATE_CONTEXT: PathLookup = type_path!(rustc_lint::LateContext);
pub static LINT: PathLookup = type_path!(rustc_lint_defs::Lint);
pub static SYMBOL: PathLookup = type_path!(rustc_span::symbol::Symbol);
pub static SYMBOL_AS_STR: PathLookup = value_path!(rustc_span::symbol::Symbol::as_str);
pub static SYM_MODULE: PathLookup = type_path!(rustc_span::symbol::sym);
pub static SYNTAX_CONTEXT: PathLookup = type_path!(rustc_span::hygiene::SyntaxContext);
#[expect(clippy::unnecessary_def_path, reason = "for uniform checking in internal lint")]
pub static TY_CTXT: PathLookup = type_path!(rustc_middle::ty::TyCtxt);

// Paths in clippy itself
pub static CLIPPY_SYM_MODULE: PathLookup = type_path!(clippy_utils::sym);
Expand Down
3 changes: 3 additions & 0 deletions clippy_lints_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ mod produce_ice;
mod symbols;
mod unnecessary_def_path;
mod unsorted_clippy_utils_paths;
mod unusual_names;

use rustc_lint::{Lint, LintStore};

Expand All @@ -59,6 +60,7 @@ static LINTS: &[&Lint] = &[
symbols::SYMBOL_AS_STR,
unnecessary_def_path::UNNECESSARY_DEF_PATH,
unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS,
unusual_names::UNUSUAL_NAMES,
];

pub fn register_lints(store: &mut LintStore) {
Expand All @@ -74,4 +76,5 @@ pub fn register_lints(store: &mut LintStore) {
store.register_late_pass(|_| Box::new(outer_expn_data_pass::OuterExpnDataPass));
store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl));
store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new()));
store.register_late_pass(|_| Box::new(unusual_names::UnusualNames));
}
4 changes: 2 additions & 2 deletions clippy_lints_internal/src/produce_ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ declare_tool_lint! {
declare_lint_pass!(ProduceIce => [PRODUCE_ICE]);

impl EarlyLintPass for ProduceIce {
fn check_fn(&mut self, ctx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {
fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {
if is_trigger_fn(fn_kind) {
ctx.sess()
cx.sess()
.dcx()
.span_delayed_bug(span, "Would you like some help with that?");
}
Expand Down
99 changes: 99 additions & 0 deletions clippy_lints_internal/src/unusual_names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::paths::PathLookup;
use clippy_utils::sym;
use itertools::Itertools;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, Pat, PatKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::kw;
use rustc_span::{Span, Symbol};

use crate::internal_paths::{APPLICABILITY, EARLY_CONTEXT, LATE_CONTEXT, TY_CTXT};

declare_tool_lint! {
/// ### What it does
/// Checks if variables of some types use the usual name.
///
/// ### Why is this bad?
/// Restricting the identifiers used for common things in
/// Clippy sources increases consistency.
///
/// ### Example
/// Check that an `rustc_errors::Applicability` variable is
/// named either `app` or `applicability`, and not
/// `a` or `appl`.
pub clippy::UNUSUAL_NAMES,
Warn,
"commonly used concepts should use usual same variable name.",
report_in_external_macro: true
}

declare_lint_pass!(UnusualNames => [UNUSUAL_NAMES]);

const USUAL_NAMES: [(&PathLookup, &str, &[Symbol]); 4] = [
(
&APPLICABILITY,
"rustc_errors::Applicability",
&[sym::app, sym::applicability],
),
(&EARLY_CONTEXT, "rustc_lint::EarlyContext", &[sym::cx]),
(&LATE_CONTEXT, "rustc_lint::LateContext", &[sym::cx]),
(&TY_CTXT, "rustc_middle::ty::TyCtxt", &[sym::tcx]),
];

impl<'tcx> LateLintPass<'tcx> for UnusualNames {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
if let StmtKind::Let(let_stmt) = stmt.kind
&& let Some(init_expr) = let_stmt.init
{
check_pat_name_for_ty(cx, let_stmt.pat, cx.typeck_results().expr_ty(init_expr), "variable");
}
}

fn check_fn(
&mut self,
cx: &LateContext<'tcx>,
kind: FnKind<'tcx>,
_decl: &'tcx FnDecl<'_>,
body: &'tcx Body<'_>,
_span: Span,
def_id: LocalDefId,
) {
if matches!(kind, FnKind::Closure) {
return;
}
for (param, ty) in body
.params
.iter()
.zip(cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder().inputs())
{
check_pat_name_for_ty(cx, param.pat, *ty, "parameter");
}
}
}

fn check_pat_name_for_ty(cx: &LateContext<'_>, pat: &Pat<'_>, ty: Ty<'_>, kind: &str) {
if let PatKind::Binding(_, _, ident, _) = pat.kind {
let ty = ty.peel_refs();
for (usual_ty, ty_str, usual_names) in USUAL_NAMES {
if usual_ty.matches_ty(cx, ty)
&& !usual_names.contains(&ident.name)
&& ident.name != kw::SelfLower
&& !ident.name.as_str().starts_with('_')
{
let usual_names = usual_names.iter().map(|name| format!("`{name}`")).join(" or ");
span_lint_and_help(
cx,
UNUSUAL_NAMES,
ident.span,
format!("unusual name for a {kind} of type `{ty_str}`"),
None,
format!("prefer using {usual_names}"),
);
}
}
}
}
9 changes: 9 additions & 0 deletions clippy_utils/src/sym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ macro_rules! generate {
//
// `cargo dev fmt` ensures that the content of the `generate!()` macro call stays sorted.
generate! {
Applicability,
AsyncReadExt,
AsyncWriteExt,
BACKSLASH_SINGLE_QUOTE: r"\'",
Expand All @@ -45,10 +46,12 @@ generate! {
Current,
DOUBLE_QUOTE: "\"",
Deserialize,
EarlyContext,
EarlyLintPass,
IntoIter,
Itertools,
LF: "\n",
LateContext,
Lazy,
Lint,
LowerExp,
Expand All @@ -75,7 +78,9 @@ generate! {
Weak,
abs,
ambiguous_glob_reexports,
app,
append,
applicability,
arg,
as_bytes,
as_deref,
Expand Down Expand Up @@ -125,6 +130,7 @@ generate! {
count_ones,
create,
create_new,
cx,
cycle,
cyclomatic_complexity,
de,
Expand Down Expand Up @@ -287,8 +293,10 @@ generate! {
rsplit_terminator,
rsplitn,
rsplitn_mut,
rustc_errors,
rustc_lint,
rustc_lint_defs,
rustc_middle,
rustc_span,
rustfmt_skip,
rwlock,
Expand Down Expand Up @@ -331,6 +339,7 @@ generate! {
symbol,
take,
take_while,
tcx,
then,
then_some,
to_ascii_lowercase,
Expand Down