Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ attribute_parsers!(
Single<RustcBuiltinMacroParser>,
Single<RustcDefPath>,
Single<RustcDeprecatedSafe2024Parser>,
Single<RustcDiagnosticItemParser>,
Single<RustcForceInlineParser>,
Single<RustcIfThisChangedParser>,
Single<RustcLayoutScalarValidRangeEndParser>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl AttributeKind {
RustcDelayedBugFromInsideQuery => No,
RustcDenyExplicitImpl(..) => No,
RustcDeprecatedSafe2024 { .. } => Yes,
RustcDiagnosticItem(..) => Yes,
RustcDummy => No,
RustcDumpDefParents => No,
RustcDumpItemBounds => No,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcDelayedBugFromInsideQuery
| AttributeKind::RustcDenyExplicitImpl(..)
| AttributeKind::RustcDeprecatedSafe2024 {..}
| AttributeKind::RustcDiagnosticItem(..)
| AttributeKind::RustcDummy
| AttributeKind::RustcDumpDefParents
| AttributeKind::RustcDumpItemBounds
Expand Down Expand Up @@ -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
Expand Down
16 changes: 5 additions & 11 deletions compiler/rustc_passes/src/diagnostic_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down Expand Up @@ -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.
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down
Loading