Port #[rustc_diagnostic_item] to the new attribute parsers
This commit is contained in:
parent
bb8b30a5fc
commit
cbc661022e
9 changed files with 61 additions and 25 deletions
|
|
@ -1103,6 +1103,45 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
|
|||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
|
||||
}
|
||||
|
||||
pub(crate) struct RustcDiagnosticItemParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcDiagnosticItemParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_diagnostic_item];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Trait),
|
||||
Allow(Target::Struct),
|
||||
Allow(Target::Enum),
|
||||
Allow(Target::MacroDef),
|
||||
Allow(Target::TyAlias),
|
||||
Allow(Target::AssocTy),
|
||||
Allow(Target::AssocConst),
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Const),
|
||||
Allow(Target::Mod),
|
||||
Allow(Target::Impl { of_trait: false }),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Crate),
|
||||
]);
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
|
||||
let Some(nv) = args.name_value() else {
|
||||
cx.expected_name_value(cx.attr_span, None);
|
||||
return None;
|
||||
};
|
||||
let Some(value) = nv.value_as_str() else {
|
||||
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
|
||||
return None;
|
||||
};
|
||||
Some(AttributeKind::RustcDiagnosticItem(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RustcSymbolName;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcSymbolName {
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ attribute_parsers!(
|
|||
Single<RustcBuiltinMacroParser>,
|
||||
Single<RustcDefPath>,
|
||||
Single<RustcDeprecatedSafe2024Parser>,
|
||||
Single<RustcDiagnosticItemParser>,
|
||||
Single<RustcForceInlineParser>,
|
||||
Single<RustcIfThisChangedParser>,
|
||||
Single<RustcLayoutScalarValidRangeEndParser>,
|
||||
|
|
|
|||
|
|
@ -919,7 +919,7 @@ impl SyntaxExtension {
|
|||
fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool {
|
||||
// FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a
|
||||
// new attribute purely for this under the `#[diagnostic]` namespace.
|
||||
ast::attr::find_by_name(attrs, sym::rustc_diagnostic_item).is_some()
|
||||
find_attr!(attrs, AttributeKind::RustcDiagnosticItem(..))
|
||||
}
|
||||
|
||||
/// Constructs a syntax extension with the given properties
|
||||
|
|
|
|||
|
|
@ -1153,6 +1153,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_deprecated_safe_2024]`
|
||||
RustcDeprecatedSafe2024 { suggestion: Symbol },
|
||||
|
||||
/// Represents `#[rustc_diagnostic_item]`
|
||||
RustcDiagnosticItem(Symbol),
|
||||
|
||||
/// Represents `#[rustc_dummy]`.
|
||||
RustcDummy,
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ impl AttributeKind {
|
|||
RustcDelayedBugFromInsideQuery => No,
|
||||
RustcDenyExplicitImpl(..) => No,
|
||||
RustcDeprecatedSafe2024 { .. } => Yes,
|
||||
RustcDiagnosticItem(..) => Yes,
|
||||
RustcDummy => No,
|
||||
RustcDumpDefParents => No,
|
||||
RustcDumpItemBounds => No,
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| AttributeKind::RustcDelayedBugFromInsideQuery
|
||||
| AttributeKind::RustcDenyExplicitImpl(..)
|
||||
| AttributeKind::RustcDeprecatedSafe2024 {..}
|
||||
| AttributeKind::RustcDiagnosticItem(..)
|
||||
| AttributeKind::RustcDummy
|
||||
| AttributeKind::RustcDumpDefParents
|
||||
| AttributeKind::RustcDumpItemBounds
|
||||
|
|
@ -398,7 +399,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| sym::panic_handler
|
||||
| sym::lang
|
||||
| sym::default_lib_allocator
|
||||
| sym::rustc_diagnostic_item
|
||||
| sym::rustc_nonnull_optimization_guaranteed
|
||||
| sym::rustc_inherit_overflow_checks
|
||||
| sym::rustc_on_unimplemented
|
||||
|
|
|
|||
|
|
@ -9,20 +9,21 @@
|
|||
//!
|
||||
//! * Compiler internal types like `Ty` and `TyCtxt`
|
||||
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::diagnostic_items::DiagnosticItems;
|
||||
use rustc_hir::{Attribute, CRATE_OWNER_ID, OwnerId};
|
||||
use rustc_hir::{CRATE_OWNER_ID, OwnerId, find_attr};
|
||||
use rustc_middle::query::{LocalCrate, Providers};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::errors::DuplicateDiagnosticItemInCrate;
|
||||
|
||||
fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) {
|
||||
let attrs = tcx.hir_attrs(owner.into());
|
||||
if let Some(name) = extract(attrs) {
|
||||
if let Some(name) = find_attr!(attrs, AttributeKind::RustcDiagnosticItem(name) => name) {
|
||||
// insert into our table
|
||||
collect_item(tcx, diagnostic_items, name, owner.to_def_id());
|
||||
collect_item(tcx, diagnostic_items, *name, owner.to_def_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,13 +54,6 @@ fn report_duplicate_item(
|
|||
});
|
||||
}
|
||||
|
||||
/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
|
||||
fn extract(attrs: &[Attribute]) -> Option<Symbol> {
|
||||
attrs.iter().find_map(|attr| {
|
||||
if attr.has_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None }
|
||||
})
|
||||
}
|
||||
|
||||
/// Traverse and collect the diagnostic items in the current
|
||||
fn diagnostic_items(tcx: TyCtxt<'_>, _: LocalCrate) -> DiagnosticItems {
|
||||
// Initialize the collector.
|
||||
|
|
|
|||
|
|
@ -1425,14 +1425,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// a note about editions
|
||||
let note = if let Some(did) = did {
|
||||
let requires_note = !did.is_local()
|
||||
&& this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any(
|
||||
|attr| {
|
||||
[sym::TryInto, sym::TryFrom, sym::FromIterator]
|
||||
.map(|x| Some(x))
|
||||
.contains(&attr.value_str())
|
||||
},
|
||||
&& find_attr!(
|
||||
this.tcx.get_all_attrs(did),
|
||||
AttributeKind::RustcDiagnosticItem(
|
||||
sym::TryInto | sym::TryFrom | sym::FromIterator
|
||||
)
|
||||
);
|
||||
|
||||
requires_note.then(|| {
|
||||
format!(
|
||||
"'{}' is included in the prelude starting in Edition 2021",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy};
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy, find_attr};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{Session, lint};
|
||||
use rustc_span::edit_distance::{edit_distance, find_best_match_for_name};
|
||||
|
|
@ -2446,10 +2446,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
.iter()
|
||||
.filter_map(|candidate| candidate.did)
|
||||
.find(|did| {
|
||||
self.r
|
||||
.tcx
|
||||
.get_attrs(*did, sym::rustc_diagnostic_item)
|
||||
.any(|attr| attr.value_str() == Some(sym::Default))
|
||||
find_attr!(
|
||||
self.r.tcx.get_all_attrs(*did),
|
||||
AttributeKind::RustcDiagnosticItem(sym::Default)
|
||||
)
|
||||
});
|
||||
let Some(default_trait) = default_trait else {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue