From d8fb164a7cfde2cdd70d2070b6e01d70a65217aa Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 9 Jun 2024 15:46:39 -0400 Subject: [PATCH] Rename `any_parent_is_automatically_derived` to `in_automatically_derived`. Only check for the attribute on an impl block. --- clippy_lints/src/default.rs | 10 +++++----- clippy_lints/src/misc.rs | 6 +++--- clippy_lints/src/no_effect.rs | 4 ++-- clippy_utils/src/lib.rs | 19 +++++++++++++++---- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs index 2b3f4854255..72fa05be3cc 100644 --- a/clippy_lints/src/default.rs +++ b/clippy_lints/src/default.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg}; use clippy_utils::source::snippet_with_context; 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_errors::Applicability; 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` && !self.reassigned_linted.contains(&expr.span) && 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 Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_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 // statements, see if they re-assign the fields of the binding let stmts_head = match block.stmts { + [] | [_] => return, // Skip the last statement since there cannot possibly be any following statements that re-assign fields. - [head @ .., _] if !head.is_empty() => head, - _ => return, + [head @ .., _] => head, }; for (stmt_idx, stmt) in stmts_head.iter().enumerate() { // 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 // only take `let ...` statements && 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() // only take bindings to identifiers && let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index f3f9bf11a61..32c8731c537 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -2,8 +2,8 @@ use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::{ - any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats, - last_path_segment, SpanlessEq, + fulfill_or_allowed, get_parent_expr, in_automatically_derived, is_lint_allowed, iter_input_pats, last_path_segment, + SpanlessEq, }; use rustc_errors::Applicability; 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<'_>) { if in_external_macro(cx.sess(), expr.span) || 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; } diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 139c33d3f4a..0ecfa7baa72 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -2,7 +2,7 @@ use clippy_utils::source::snippet_opt; use clippy_utils::ty::has_drop; 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_hir::def::{DefKind, Res}; @@ -187,7 +187,7 @@ fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool { && has_no_effect(cx, init) && let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind && 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() { l.push(hir_id); diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 28d1eeb4e28..c24cb12845b 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -103,8 +103,9 @@ use rustc_hir::{ self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, - ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, - PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, + ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat, + PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, + TyKind, UnOp, }; use rustc_lexer::{tokenize, TokenKind}; 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 } -pub fn any_parent_is_automatically_derived(tcx: TyCtxt<'_>, node: HirId) -> bool { - any_parent_has_attr(tcx, node, sym::automatically_derived) +/// Checks if the given HIR node is inside an `impl` block with the `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.