Remove MacroKind::ProcMacroStub
It's internal to resolve and always results in `Res::Err` outside of resolve. Instead put `DefKind::Fn`s themselves into the macro namespace, it's ok. Proc macro stubs are items placed into macro namespase for functions that define proc macros. https://github.com/rust-lang/rust/pull/52383 The rustdoc test is changed because the old test didn't actually reproduce the ICE it was supposed to reproduce.
This commit is contained in:
parent
c6a9e766f9
commit
48635226d8
10 changed files with 35 additions and 53 deletions
|
|
@ -29,7 +29,7 @@ use syntax::attr;
|
|||
|
||||
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
|
||||
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
|
||||
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||
use syntax::ext::base::SyntaxExtension;
|
||||
use syntax::ext::base::Determinacy::Undetermined;
|
||||
use syntax::ext::hygiene::Mark;
|
||||
use syntax::ext::tt::macro_rules;
|
||||
|
|
@ -46,6 +46,20 @@ use log::debug;
|
|||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
fn proc_macro_stub(item: &Item) -> Option<(Ident, Span)> {
|
||||
if attr::contains_name(&item.attrs, sym::proc_macro) ||
|
||||
attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
|
||||
return Some((item.ident, item.span));
|
||||
} else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
|
||||
if let Some(nested_meta) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
|
||||
if let Some(ident) = nested_meta.ident() {
|
||||
return Some((ident, ident.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBinding {
|
||||
|
|
@ -456,22 +470,8 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
// Functions introducing procedural macros reserve a slot
|
||||
// in the macro namespace as well (see #52225).
|
||||
if attr::contains_name(&item.attrs, sym::proc_macro) ||
|
||||
attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
|
||||
let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id());
|
||||
self.define(parent, ident, MacroNS, (res, vis, sp, expansion));
|
||||
}
|
||||
if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
|
||||
if let Some(trait_attr) =
|
||||
attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
|
||||
if let Some(ident) = trait_attr.ident() {
|
||||
let res = Res::Def(
|
||||
DefKind::Macro(MacroKind::ProcMacroStub),
|
||||
res.def_id(),
|
||||
);
|
||||
self.define(parent, ident, MacroNS, (res, vis, ident.span, expansion));
|
||||
}
|
||||
}
|
||||
if let Some((ident, span)) = proc_macro_stub(item) {
|
||||
self.define(parent, ident, MacroNS, (res, vis, span, expansion));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -778,8 +778,6 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
crate fn opt_get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
|
||||
let def_id = match res {
|
||||
Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) =>
|
||||
return Some(self.non_macro_attr(true)), // some dummy extension
|
||||
Res::Def(DefKind::Macro(..), def_id) => def_id,
|
||||
Res::NonMacroAttr(attr_kind) =>
|
||||
return Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
|
||||
|
|
|
|||
|
|
@ -102,12 +102,11 @@ fn sub_namespace_match(candidate: Option<MacroKind>, requirement: Option<MacroKi
|
|||
#[derive(PartialEq)]
|
||||
enum SubNS { Bang, AttrLike }
|
||||
let sub_ns = |kind| match kind {
|
||||
MacroKind::Bang => Some(SubNS::Bang),
|
||||
MacroKind::Attr | MacroKind::Derive => Some(SubNS::AttrLike),
|
||||
MacroKind::ProcMacroStub => None,
|
||||
MacroKind::Bang => SubNS::Bang,
|
||||
MacroKind::Attr | MacroKind::Derive => SubNS::AttrLike,
|
||||
};
|
||||
let requirement = requirement.and_then(|kind| sub_ns(kind));
|
||||
let candidate = candidate.and_then(|kind| sub_ns(kind));
|
||||
let candidate = candidate.map(sub_ns);
|
||||
let requirement = requirement.map(sub_ns);
|
||||
// "No specific sub-namespace" means "matches anything" for both requirements and candidates.
|
||||
candidate.is_none() || requirement.is_none() || candidate == requirement
|
||||
}
|
||||
|
|
@ -310,15 +309,15 @@ impl<'a> Resolver<'a> {
|
|||
let res = res?;
|
||||
|
||||
match res {
|
||||
Res::Def(DefKind::Macro(macro_kind), def_id) => {
|
||||
Res::Def(DefKind::Macro(_), def_id) => {
|
||||
if let Some(node_id) = self.definitions.as_local_node_id(def_id) {
|
||||
self.unused_macros.remove(&node_id);
|
||||
}
|
||||
if macro_kind == MacroKind::ProcMacroStub {
|
||||
let msg = "can't use a procedural macro from the same crate that defines it";
|
||||
self.session.span_err(path.span, msg);
|
||||
return Err(Determinacy::Determined);
|
||||
}
|
||||
}
|
||||
Res::Def(DefKind::Fn, _) => {
|
||||
let msg = "can't use a procedural macro from the same crate that defines it";
|
||||
self.session.span_err(path.span, msg);
|
||||
return Err(Determinacy::Determined);
|
||||
}
|
||||
Res::NonMacroAttr(attr_kind) => {
|
||||
if kind == MacroKind::Attr {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue