Rename any_parent_is_automatically_derived to in_automatically_derived. Only check for the attribute on an impl block.

This commit is contained in:
Jason Newcomb 2024-06-09 15:46:39 -04:00
parent 3ed690f07a
commit d8fb164a7c
4 changed files with 25 additions and 14 deletions

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg}; use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
use clippy_utils::source::snippet_with_context; use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::{has_drop, is_copy}; use clippy_utils::ty::{has_drop, is_copy};
use clippy_utils::{any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro}; use clippy_utils::{contains_name, get_parent_expr, in_automatically_derived, is_from_proc_macro};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
@ -84,7 +84,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Avoid cases already linted by `field_reassign_with_default` // Avoid cases already linted by `field_reassign_with_default`
&& !self.reassigned_linted.contains(&expr.span) && !self.reassigned_linted.contains(&expr.span)
&& let ExprKind::Call(path, ..) = expr.kind && let ExprKind::Call(path, ..) = expr.kind
&& !any_parent_is_automatically_derived(cx.tcx, expr.hir_id) && !in_automatically_derived(cx.tcx, expr.hir_id)
&& let ExprKind::Path(ref qpath) = path.kind && let ExprKind::Path(ref qpath) = path.kind
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
&& cx.tcx.is_diagnostic_item(sym::default_fn, def_id) && cx.tcx.is_diagnostic_item(sym::default_fn, def_id)
@ -113,9 +113,9 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
// start from the `let mut _ = _::default();` and look at all the following // start from the `let mut _ = _::default();` and look at all the following
// statements, see if they re-assign the fields of the binding // statements, see if they re-assign the fields of the binding
let stmts_head = match block.stmts { let stmts_head = match block.stmts {
[] | [_] => return,
// Skip the last statement since there cannot possibly be any following statements that re-assign fields. // Skip the last statement since there cannot possibly be any following statements that re-assign fields.
[head @ .., _] if !head.is_empty() => head, [head @ .., _] => head,
_ => return,
}; };
for (stmt_idx, stmt) in stmts_head.iter().enumerate() { for (stmt_idx, stmt) in stmts_head.iter().enumerate() {
// find all binding statements like `let mut _ = T::default()` where `T::default()` is the // find all binding statements like `let mut _ = T::default()` where `T::default()` is the
@ -124,7 +124,7 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
let (local, variant, binding_name, binding_type, span) = if let StmtKind::Let(local) = stmt.kind let (local, variant, binding_name, binding_type, span) = if let StmtKind::Let(local) = stmt.kind
// only take `let ...` statements // only take `let ...` statements
&& let Some(expr) = local.init && let Some(expr) = local.init
&& !any_parent_is_automatically_derived(cx.tcx, expr.hir_id) && !in_automatically_derived(cx.tcx, expr.hir_id)
&& !expr.span.from_expansion() && !expr.span.from_expansion()
// only take bindings to identifiers // only take bindings to identifiers
&& let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind && let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind

View File

@ -2,8 +2,8 @@
use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::source::{snippet, snippet_with_context};
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::{ use clippy_utils::{
any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats, fulfill_or_allowed, get_parent_expr, in_automatically_derived, is_lint_allowed, iter_input_pats, last_path_segment,
last_path_segment, SpanlessEq, SpanlessEq,
}; };
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
@ -206,7 +206,7 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if in_external_macro(cx.sess(), expr.span) if in_external_macro(cx.sess(), expr.span)
|| expr.span.desugaring_kind().is_some() || expr.span.desugaring_kind().is_some()
|| any_parent_is_automatically_derived(cx.tcx, expr.hir_id) || in_automatically_derived(cx.tcx, expr.hir_id)
{ {
return; return;
} }

View File

@ -2,7 +2,7 @@
use clippy_utils::source::snippet_opt; use clippy_utils::source::snippet_opt;
use clippy_utils::ty::has_drop; use clippy_utils::ty::has_drop;
use clippy_utils::{ use clippy_utils::{
any_parent_is_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks, in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
}; };
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -187,7 +187,7 @@ fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
&& has_no_effect(cx, init) && has_no_effect(cx, init)
&& let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind && let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind
&& ident.name.to_ident_string().starts_with('_') && ident.name.to_ident_string().starts_with('_')
&& !any_parent_is_automatically_derived(cx.tcx, local.hir_id) && !in_automatically_derived(cx.tcx, local.hir_id)
{ {
if let Some(l) = self.local_bindings.last_mut() { if let Some(l) = self.local_bindings.last_mut() {
l.push(hir_id); l.push(hir_id);

View File

@ -103,8 +103,9 @@
use rustc_hir::{ use rustc_hir::{
self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstContext, self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstContext,
Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
TyKind, UnOp,
}; };
use rustc_lexer::{tokenize, TokenKind}; use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, Level, Lint, LintContext}; use rustc_lint::{LateContext, Level, Lint, LintContext};
@ -1924,8 +1925,18 @@ pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool
false false
} }
pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool { /// Checks if the given HIR node is inside an `impl` block with the `automatically_derived`
any_parent_has_attr(tcx, node, sym::automatically_derived) /// attribute.
pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool {
tcx.hir()
.parent_owner_iter(id)
.filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_))))
.any(|(id, _)| {
has_attr(
tcx.hir().attrs(tcx.local_def_id_to_hir_id(id.def_id)),
sym::automatically_derived,
)
})
} }
/// Matches a function call with the given path and returns the arguments. /// Matches a function call with the given path and returns the arguments.