From 431aefb2d4d579b152f7f26f3e70d2fdc3db4bfb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 12 Jul 2018 13:24:59 +0300 Subject: Functions introducing procedural macros reserve a slot in the macro namespace as well --- src/librustc_resolve/build_reduced_graph.rs | 20 +++++++++++++++++++- src/librustc_resolve/macros.rs | 17 +++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'src/librustc_resolve') diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a770f078404..29312912a24 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -34,7 +34,7 @@ use syntax::attr; use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId}; use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind, Variant}; -use syntax::ext::base::SyntaxExtension; +use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::base::Determinacy::Undetermined; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; @@ -335,6 +335,24 @@ impl<'a> Resolver<'a> { ItemKind::Fn(..) => { let def = Def::Fn(self.definitions.local_def_id(item.id)); self.define(parent, ident, ValueNS, (def, vis, sp, expansion)); + + // Functions introducing procedural macros reserve a slot + // in the macro namespace as well (see #52225). + if attr::contains_name(&item.attrs, "proc_macro") || + attr::contains_name(&item.attrs, "proc_macro_attribute") { + let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub); + self.define(parent, ident, MacroNS, (def, vis, sp, expansion)); + } + if let Some(attr) = attr::find_by_name(&item.attrs, "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.name().map(Ident::with_empty_ctxt) { + let sp = trait_attr.span; + let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub); + self.define(parent, ident, MacroNS, (def, vis, sp, expansion)); + } + } + } } // These items live in the type namespace. diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 024506ed7f8..c99172efc7c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -321,6 +321,10 @@ impl<'a> base::Resolver for Resolver<'a> { InvocationKind::Attr { attr: None, .. } => return Ok(None), _ => self.resolve_invoc_to_def(invoc, scope, force)?, }; + if let Def::Macro(_, MacroKind::ProcMacroStub) = def { + self.report_proc_macro_stub(invoc.span()); + return Err(Determinacy::Determined); + } let def_id = def.def_id(); self.macro_defs.insert(invoc.expansion_data.mark, def_id); @@ -338,9 +342,13 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result, Determinacy> { - self.resolve_macro_to_def(scope, path, kind, force).map(|def| { + self.resolve_macro_to_def(scope, path, kind, force).and_then(|def| { + if let Def::Macro(_, MacroKind::ProcMacroStub) = def { + self.report_proc_macro_stub(path.span); + return Err(Determinacy::Determined); + } self.unused_macros.remove(&def.def_id()); - self.get_macro(def) + Ok(self.get_macro(def)) }) } @@ -363,6 +371,11 @@ impl<'a> base::Resolver for Resolver<'a> { } impl<'a> Resolver<'a> { + fn report_proc_macro_stub(&self, span: Span) { + self.session.span_err(span, + "can't use a procedural macro from the same crate that defines it"); + } + fn resolve_invoc_to_def(&mut self, invoc: &mut Invocation, scope: Mark, force: bool) -> Result { let (attr, traits, item) = match invoc.kind { -- cgit 1.4.1-3-g733a5