Port #[automatically_derived] to the new attribute parsing infrastructure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
This commit is contained in:
@@ -217,6 +217,10 @@ impl AttributeExt for Attribute {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_automatically_derived_attr(&self) -> bool {
|
||||||
|
self.has_name(sym::automatically_derived)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attribute {
|
impl Attribute {
|
||||||
@@ -810,6 +814,7 @@ pub trait AttributeExt: Debug {
|
|||||||
.iter()
|
.iter()
|
||||||
.any(|kind| self.has_name(*kind))
|
.any(|kind| self.has_name(*kind))
|
||||||
}
|
}
|
||||||
|
fn is_automatically_derived_attr(&self) -> bool;
|
||||||
|
|
||||||
/// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
|
/// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
|
||||||
/// * `///doc` returns `Some(("doc", CommentKind::Line))`.
|
/// * `///doc` returns `Some(("doc", CommentKind::Line))`.
|
||||||
|
|||||||
@@ -207,6 +207,9 @@ pub enum AttributeKind {
|
|||||||
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
||||||
AsPtr(Span),
|
AsPtr(Span),
|
||||||
|
|
||||||
|
/// Represents `#[automatically_derived]`
|
||||||
|
AutomaticallyDerived(Span),
|
||||||
|
|
||||||
/// Represents `#[rustc_default_body_unstable]`.
|
/// Represents `#[rustc_default_body_unstable]`.
|
||||||
BodyStability {
|
BodyStability {
|
||||||
stability: DefaultBodyStability,
|
stability: DefaultBodyStability,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ impl AttributeKind {
|
|||||||
AllowIncoherentImpl(..) => No,
|
AllowIncoherentImpl(..) => No,
|
||||||
AllowInternalUnstable(..) => Yes,
|
AllowInternalUnstable(..) => Yes,
|
||||||
AsPtr(..) => Yes,
|
AsPtr(..) => Yes,
|
||||||
|
AutomaticallyDerived(..) => Yes,
|
||||||
BodyStability { .. } => No,
|
BodyStability { .. } => No,
|
||||||
CoherenceIsCore => No,
|
CoherenceIsCore => No,
|
||||||
Coinductive(..) => No,
|
Coinductive(..) => No,
|
||||||
|
|||||||
@@ -24,3 +24,10 @@ impl<S: Stage> NoArgsAttributeParser<S> for PassByValueParser {
|
|||||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue;
|
const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct AutomaticallyDerivedParser;
|
||||||
|
impl<S: Stage> NoArgsAttributeParser<S> for AutomaticallyDerivedParser {
|
||||||
|
const PATH: &[Symbol] = &[sym::automatically_derived];
|
||||||
|
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||||
|
const CREATE: fn(Span) -> AttributeKind = AttributeKind::AutomaticallyDerived;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ use crate::attributes::link_attrs::{
|
|||||||
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
|
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser,
|
||||||
StdInternalSymbolParser,
|
StdInternalSymbolParser,
|
||||||
};
|
};
|
||||||
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
|
use crate::attributes::lint_helpers::{
|
||||||
|
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
|
||||||
|
};
|
||||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||||
use crate::attributes::must_use::MustUseParser;
|
use crate::attributes::must_use::MustUseParser;
|
||||||
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
|
||||||
@@ -153,6 +155,7 @@ attribute_parsers!(
|
|||||||
Single<TransparencyParser>,
|
Single<TransparencyParser>,
|
||||||
Single<WithoutArgs<AllowIncoherentImplParser>>,
|
Single<WithoutArgs<AllowIncoherentImplParser>>,
|
||||||
Single<WithoutArgs<AsPtrParser>>,
|
Single<WithoutArgs<AsPtrParser>>,
|
||||||
|
Single<WithoutArgs<AutomaticallyDerivedParser>>,
|
||||||
Single<WithoutArgs<CoherenceIsCoreParser>>,
|
Single<WithoutArgs<CoherenceIsCoreParser>>,
|
||||||
Single<WithoutArgs<CoinductiveParser>>,
|
Single<WithoutArgs<CoinductiveParser>>,
|
||||||
Single<WithoutArgs<ColdParser>>,
|
Single<WithoutArgs<ColdParser>>,
|
||||||
|
|||||||
@@ -1304,6 +1304,7 @@ impl AttributeExt for Attribute {
|
|||||||
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
|
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
|
||||||
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
|
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
|
||||||
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
|
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
|
||||||
|
Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span,
|
||||||
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
|
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1334,6 +1335,11 @@ impl AttributeExt for Attribute {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_automatically_derived_attr(&self) -> bool {
|
||||||
|
matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
|
fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
|
||||||
match &self {
|
match &self {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::{Applicability, Diag};
|
use rustc_errors::{Applicability, Diag};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@@ -62,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
|
|||||||
let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return };
|
let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return };
|
||||||
let assoc = cx.tcx.associated_item(impl_item.owner_id);
|
let assoc = cx.tcx.associated_item(impl_item.owner_id);
|
||||||
let parent = assoc.container_id(cx.tcx);
|
let parent = assoc.container_id(cx.tcx);
|
||||||
if cx.tcx.has_attr(parent, sym::automatically_derived) {
|
if find_attr!(cx.tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) {
|
||||||
// We don't care about what `#[derive(Default)]` produces in this lint.
|
// We don't care about what `#[derive(Default)]` produces in this lint.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -644,7 +644,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
|||||||
) {
|
) {
|
||||||
let sess = self.sess;
|
let sess = self.sess;
|
||||||
for (attr_index, attr) in attrs.iter().enumerate() {
|
for (attr_index, attr) in attrs.iter().enumerate() {
|
||||||
if attr.has_name(sym::automatically_derived) {
|
if attr.is_automatically_derived_attr() {
|
||||||
self.insert(
|
self.insert(
|
||||||
LintId::of(SINGLE_USE_LIFETIMES),
|
LintId::of(SINGLE_USE_LIFETIMES),
|
||||||
LevelAndSource {
|
LevelAndSource {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, V
|
|||||||
use rustc_ast::expand::StrippedCfgItem;
|
use rustc_ast::expand::StrippedCfgItem;
|
||||||
use rustc_ast::node_id::NodeMap;
|
use rustc_ast::node_id::NodeMap;
|
||||||
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
|
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
|
||||||
use rustc_attr_data_structures::AttributeKind;
|
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
@@ -2031,7 +2031,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
|
|
||||||
/// Check if the given `DefId` is `#\[automatically_derived\]`.
|
/// Check if the given `DefId` is `#\[automatically_derived\]`.
|
||||||
pub fn is_automatically_derived(self, def_id: DefId) -> bool {
|
pub fn is_automatically_derived(self, def_id: DefId) -> bool {
|
||||||
self.has_attr(def_id, sym::automatically_derived)
|
find_attr!(self.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use core::ops::ControlFlow;
|
|||||||
|
|
||||||
use rustc_abi::{FieldIdx, VariantIdx};
|
use rustc_abi::{FieldIdx, VariantIdx};
|
||||||
use rustc_apfloat::Float;
|
use rustc_apfloat::Float;
|
||||||
|
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Diag;
|
use rustc_errors::Diag;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@@ -15,7 +16,7 @@ use rustc_middle::ty::{
|
|||||||
};
|
};
|
||||||
use rustc_middle::{mir, span_bug};
|
use rustc_middle::{mir, span_bug};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::{DUMMY_SP, Span, sym};
|
use rustc_span::{DUMMY_SP, Span};
|
||||||
use rustc_trait_selection::traits::ObligationCause;
|
use rustc_trait_selection::traits::ObligationCause;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
@@ -495,7 +496,8 @@ fn type_has_partial_eq_impl<'tcx>(
|
|||||||
let mut structural_peq = false;
|
let mut structural_peq = false;
|
||||||
let mut impl_def_id = None;
|
let mut impl_def_id = None;
|
||||||
for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
|
for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
|
||||||
automatically_derived = tcx.has_attr(def_id, sym::automatically_derived);
|
automatically_derived =
|
||||||
|
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..));
|
||||||
impl_def_id = Some(def_id);
|
impl_def_id = Some(def_id);
|
||||||
}
|
}
|
||||||
for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
|
for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
|
||||||
|
|||||||
@@ -316,6 +316,7 @@ pub fn check_builtin_meta_item(
|
|||||||
| sym::rustc_layout_scalar_valid_range_start
|
| sym::rustc_layout_scalar_valid_range_start
|
||||||
| sym::rustc_layout_scalar_valid_range_end
|
| sym::rustc_layout_scalar_valid_range_end
|
||||||
| sym::no_implicit_prelude
|
| sym::no_implicit_prelude
|
||||||
|
| sym::automatically_derived
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
|
Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
|
||||||
self.check_confusables(*first_span, target);
|
self.check_confusables(*first_span, target);
|
||||||
}
|
}
|
||||||
|
Attribute::Parsed(AttributeKind::AutomaticallyDerived(attr_span)) => self
|
||||||
|
.check_generic_attr(
|
||||||
|
hir_id,
|
||||||
|
sym::automatically_derived,
|
||||||
|
*attr_span,
|
||||||
|
target,
|
||||||
|
Target::Impl,
|
||||||
|
),
|
||||||
Attribute::Parsed(
|
Attribute::Parsed(
|
||||||
AttributeKind::Stability { span, .. }
|
AttributeKind::Stability { span, .. }
|
||||||
| AttributeKind::ConstStability { span, .. },
|
| AttributeKind::ConstStability { span, .. },
|
||||||
@@ -335,9 +343,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
[sym::should_panic, ..] => {
|
[sym::should_panic, ..] => {
|
||||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
|
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
|
||||||
}
|
}
|
||||||
[sym::automatically_derived, ..] => {
|
|
||||||
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl)
|
|
||||||
}
|
|
||||||
[sym::proc_macro, ..] => {
|
[sym::proc_macro, ..] => {
|
||||||
self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike)
|
self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike)
|
||||||
}
|
}
|
||||||
@@ -2814,7 +2819,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||||||
// resolution for the attribute macro error.
|
// resolution for the attribute macro error.
|
||||||
const ATTRS_TO_CHECK: &[Symbol] = &[
|
const ATTRS_TO_CHECK: &[Symbol] = &[
|
||||||
sym::macro_export,
|
sym::macro_export,
|
||||||
sym::automatically_derived,
|
|
||||||
sym::rustc_main,
|
sym::rustc_main,
|
||||||
sym::derive,
|
sym::derive,
|
||||||
sym::test,
|
sym::test,
|
||||||
@@ -2837,6 +2841,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||||||
(*first_attr_span, sym::repr)
|
(*first_attr_span, sym::repr)
|
||||||
} else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
|
} else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
|
||||||
(*span, sym::path)
|
(*span, sym::path)
|
||||||
|
} else if let Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) = attr {
|
||||||
|
(*span, sym::automatically_derived)
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ use rustc_middle::query::Providers;
|
|||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
|
use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::{BytePos, Span, Symbol, sym};
|
use rustc_span::{BytePos, Span, Symbol};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use self::LiveNodeKind::*;
|
use self::LiveNodeKind::*;
|
||||||
@@ -140,7 +140,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
// Don't run unused pass for #[derive()]
|
// Don't run unused pass for #[derive()]
|
||||||
let parent = tcx.local_parent(def_id);
|
let parent = tcx.local_parent(def_id);
|
||||||
if let DefKind::Impl { .. } = tcx.def_kind(parent)
|
if let DefKind::Impl { .. } = tcx.def_kind(parent)
|
||||||
&& tcx.has_attr(parent, sym::automatically_derived)
|
&& find_attr!(tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user