about summary refs log tree commit diff
path: root/src/librustc_resolve
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-15 19:35:06 +0000
committerbors <bors@rust-lang.org>2018-07-15 19:35:06 +0000
commit82e5c9c8e2c4f47a8e1090ad8e6be5a16f82795e (patch)
tree17ebf48a20a33d0dd196b291c954bf4502fbe3b6 /src/librustc_resolve
parentfb8bde03cf0a024c076581824ccf5ede422a613d (diff)
parent431aefb2d4d579b152f7f26f3e70d2fdc3db4bfb (diff)
downloadrust-82e5c9c8e2c4f47a8e1090ad8e6be5a16f82795e.tar.gz
rust-82e5c9c8e2c4f47a8e1090ad8e6be5a16f82795e.zip
Auto merge of #52383 - petrochenkov:pmns, r=alexcrichton
resolve: Functions introducing procedural macros reserve a slot in the macro namespace as well

Similarly to https://github.com/rust-lang/rust/pull/52234, this gives us symmetry between internal and external views of a crate, but in this case it's always an error to call a procedural macro in the same crate in which it's defined.

Closes https://github.com/rust-lang/rust/issues/52225
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 {