Ports #[macro_use] and #[macro_escape] to the new attribute parsing infrastructure

This commit is contained in:
Jonathan Brouwer
2025-07-12 17:42:39 +02:00
parent a7a1618e6c
commit a460b46d0f
15 changed files with 206 additions and 65 deletions

View File

@@ -11,11 +11,14 @@ use std::sync::Arc;
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
ForeignItemKind, Impl, Item, ItemKind, MetaItemKind, NodeId, StaticItem, StmtKind, TyAlias,
ForeignItemKind, Impl, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
};
use rustc_attr_data_structures::{AttributeKind, MacroUseArgs};
use rustc_attr_parsing as attr;
use rustc_attr_parsing::AttributeParser;
use rustc_expand::base::ResolverExpand;
use rustc_expand::expand::AstFragment;
use rustc_hir::Attribute;
use rustc_hir::def::{self, *};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_index::bit_set::DenseBitSet;
@@ -25,6 +28,7 @@ use rustc_middle::metadata::ModChild;
use rustc_middle::ty::{Feed, Visibility};
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
use rustc_span::{Ident, Span, Symbol, kw, sym};
use thin_vec::ThinVec;
use tracing::debug;
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
@@ -1019,42 +1023,31 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
/// Returns `true` if we should consider the underlying `extern crate` to be used.
fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
let mut import_all = None;
let mut single_imports = Vec::new();
for attr in &item.attrs {
if attr.has_name(sym::macro_use) {
if self.parent_scope.module.parent.is_some() {
self.r.dcx().emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot {
span: item.span,
});
}
if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
&& orig_name == kw::SelfLower
{
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
let ill_formed = |span| {
self.r.dcx().emit_err(errors::BadMacroImport { span });
};
match attr.meta() {
Some(meta) => match meta.kind {
MetaItemKind::Word => {
import_all = Some(meta.span);
break;
}
MetaItemKind::List(meta_item_inners) => {
for meta_item_inner in meta_item_inners {
match meta_item_inner.ident() {
Some(ident) if meta_item_inner.is_word() => {
single_imports.push(ident)
}
_ => ill_formed(meta_item_inner.span()),
}
}
}
MetaItemKind::NameValue(..) => ill_formed(meta.span),
},
None => ill_formed(attr.span),
}
let mut single_imports = ThinVec::new();
if let Some(Attribute::Parsed(AttributeKind::MacroUse { span, arguments })) =
AttributeParser::parse_limited(
self.r.tcx.sess,
&item.attrs,
sym::macro_use,
item.span,
item.id,
None,
)
{
if self.parent_scope.module.parent.is_some() {
self.r
.dcx()
.emit_err(errors::ExternCrateLoadingMacroNotAtCrateRoot { span: item.span });
}
if let ItemKind::ExternCrate(Some(orig_name), _) = item.kind
&& orig_name == kw::SelfLower
{
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span });
}
match arguments {
MacroUseArgs::UseAll => import_all = Some(span),
MacroUseArgs::UseSpecific(imports) => single_imports = imports,
}
}

View File

@@ -815,13 +815,6 @@ pub(crate) struct ExternCrateLoadingMacroNotAtCrateRoot {
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(resolve_bad_macro_import, code = E0466)]
pub(crate) struct BadMacroImport {
#[primary_span]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(resolve_extern_crate_self_requires_renaming)]
pub(crate) struct ExternCrateSelfRequiresRenaming {