diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index f56a4d7308e90..0b5eb22157830 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -808,6 +808,7 @@ impl !Sync for *mut T {} /// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] +#[clippy::no_dead_code_warning] pub struct PhantomData; #[stable(feature = "rust1", since = "1.0.0")] @@ -1023,6 +1024,7 @@ pub auto trait Unpin {} // will likely eventually be deprecated, and all new code should be using `UnsafePinned` instead. #[stable(feature = "pin", since = "1.33.0")] #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[clippy::no_dead_code_warning] pub struct PhantomPinned; #[stable(feature = "pin", since = "1.33.0")] diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 332c19e140b3e..790a4d7fb7360 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -2,13 +2,13 @@ use std::ops::ControlFlow; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::{MaybeDef, MaybeResPath}; -use clippy_utils::sym; +use clippy_utils::{is_clippy_no_dead_code_warning_attr, sym}; use clippy_utils::visitors::{Visitable, for_each_expr}; use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_hir::{Block, Expr, ExprKind, Impl, Item, ItemKind, Node, QPath, TyKind, VariantData}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{Ty, TypeckResults}; use rustc_session::declare_lint_pass; use rustc_span::{Span, Symbol}; @@ -184,7 +184,8 @@ fn check_struct<'tcx>( .iter() .filter_map(|field| { if field_accesses.contains(&field.ident.name) - || field.ty.basic_res().is_lang_item(cx, LangItem::PhantomData) + // We exclude certain types (e.g. PhantomData, PhantomPinned) marked with + || is_clippy_no_dead_code_warning_attr(cx.sess(), cx.tcx, field.ty.basic_res()) { None } else { diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs index 64724f7d01d00..9a6b5ff13e8d8 100644 --- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs +++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs @@ -1,10 +1,10 @@ use clippy_config::Conf; use clippy_config::types::PubUnderscoreFieldsBehaviour; -use clippy_utils::attrs::is_doc_hidden; +use clippy_utils::attrs::{is_doc_hidden, is_clippy_no_dead_code_warning_attr}; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::res::{MaybeDef, MaybeResPath}; -use rustc_hir::{FieldDef, Item, ItemKind, LangItem}; -use rustc_lint::{LateContext, LateLintPass}; +use clippy_utils::res::{MaybeResPath}; +use rustc_hir::{FieldDef, Item, ItemKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; declare_clippy_lint! { @@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { // We ignore fields that have `#[doc(hidden)]`. && !is_doc_hidden(cx.tcx.hir_attrs(field.hir_id)) // We ignore fields that are `PhantomData`. - && !field.ty.basic_res().is_lang_item(cx, LangItem::PhantomData) + && !is_clippy_no_dead_code_warning_attr(cx.sess(), cx.tcx, field.ty.basic_res()) { span_lint_hir_and_then( cx, diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 6e74347713695..40b535c239b9b 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -4,6 +4,7 @@ use crate::source::SpanRangeExt; use crate::{sym, tokenize_with_text}; use rustc_ast::attr::AttributeExt; use rustc_errors::Applicability; +use rustc_hir::def::Res; use rustc_hir::find_attr; use rustc_lexer::TokenKind; use rustc_lint::LateContext; @@ -35,6 +36,7 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( // The following attributes are for the 3rd party crate authors. // See book/src/attribs.md | sym::has_significant_drop + | sym::no_dead_code_warning | sym::format_args => None, _ => { sess.dcx().span_err(path_span, "usage of unknown attribute"); @@ -91,6 +93,16 @@ pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { attrs.iter().any(AttributeExt::is_doc_hidden) } +/// Checks whether the original type is marked as `#[rustc_no_dead_code_warning]` +pub fn is_clippy_no_dead_code_warning_attr<'a>(sess: &'a Session, tcx: TyCtxt<'_>, res: &Res) -> bool { + res.opt_def_id().map(|def_id| get_builtin_attr( + sess, + #[allow(deprecated)] + tcx.get_all_attrs(def_id), + sym::no_dead_code_warning, + ).next().is_some()).unwrap_or(false) +} + /// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]` pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool { adt.is_variant_list_non_exhaustive() diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index 4eaeafe127078..f61330102a48c 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs @@ -439,6 +439,7 @@ generate! { next_if_eq, next_multiple_of, next_tuple, + no_dead_code_warning, nth, ok, ok_or,