about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-07-12 13:24:59 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-07-14 20:10:07 +0300
commit431aefb2d4d579b152f7f26f3e70d2fdc3db4bfb (patch)
treec30139184897e67a9138bc21109ddb0be9064f7f /src/librustc_resolve
parent1731f0af22af16c461b2b7abe58988b8549b2de6 (diff)
downloadrust-431aefb2d4d579b152f7f26f3e70d2fdc3db4bfb.tar.gz
rust-431aefb2d4d579b152f7f26f3e70d2fdc3db4bfb.zip
Functions introducing procedural macros reserve a slot in the macro namespace as well
Diffstat (limited to 'src/librustc_resolve')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs20
-rw-r--r--src/librustc_resolve/macros.rs17
2 files changed, 34 insertions, 3 deletions
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<Lrc<SyntaxExtension>, 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<Def, Determinacy> {
         let (attr, traits, item) = match invoc.kind {