about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/map/mod.rs13
-rw-r--r--src/librustc_privacy/lib.rs60
-rw-r--r--src/test/ui/macros/macro-in-fn.rs9
-rw-r--r--src/test/ui/macros/macro-in-fn.stderr8
4 files changed, 58 insertions, 32 deletions
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 7292428ec37..5bf310ce8d9 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -514,8 +514,11 @@ impl<'hir> Map<'hir> {
         &self.forest.krate.attrs
     }
 
-    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId)
-    {
+    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
+        self.get_if_module(module).expect("not a module")
+    }
+
+    pub fn get_if_module(&self, module: DefId) -> Option<(&'hir Mod, Span, HirId)> {
         let hir_id = self.as_local_hir_id(module).unwrap();
         self.read(hir_id);
         match self.find_entry(hir_id).unwrap().node {
@@ -523,9 +526,9 @@ impl<'hir> Map<'hir> {
                 span,
                 node: ItemKind::Mod(ref m),
                 ..
-            }) => (m, span, hir_id),
-            Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
-            _ => panic!("not a module")
+            }) => Some((m, span, hir_id)),
+            Node::Crate => Some((&self.forest.krate.module, self.forest.krate.span, hir_id)),
+            _ => None,
         }
     }
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index bca77621e55..dc787d22538 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -508,39 +508,45 @@ impl EmbargoVisitor<'tcx> {
         }
     }
 
-    fn update_macro_reachable_mod(
-        &mut self,
-        reachable_mod: hir::HirId,
-        defining_mod: DefId,
-    ) {
-        let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
-        let module = self.tcx.hir().get_module(module_def_id).0;
-        for item_id in &module.item_ids {
-            let hir_id = item_id.id;
-            let item_def_id = self.tcx.hir().local_def_id(hir_id);
-            if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
-                let item = self.tcx.hir().expect_item(hir_id);
-                let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
-                self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
+    fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) {
+        let set_vis = |this: &mut Self, hir_id: hir::HirId| {
+            let item_def_id = this.tcx.hir().local_def_id(hir_id);
+            if let Some(def_kind) = this.tcx.def_kind(item_def_id) {
+                let item = this.tcx.hir().expect_item(hir_id);
+                let vis = ty::Visibility::from_hir(&item.vis, hir_id, this.tcx);
+                this.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
             }
-        }
+        };
 
-        if let Some(exports) = self.tcx.module_exports(module_def_id) {
-            for export in exports {
-                if export.vis.is_accessible_from(defining_mod, self.tcx) {
-                    if let Res::Def(def_kind, def_id) = export.res {
-                        let vis = def_id_visibility(self.tcx, def_id).0;
-                        if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
-                            self.update_macro_reachable_def(
-                                hir_id,
-                                def_kind,
-                                vis,
-                                defining_mod,
-                            );
+        let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
+        if let Some((module, _, _)) = self.tcx.hir().get_if_module(module_def_id) {
+            for item_id in &module.item_ids {
+                let hir_id = item_id.id;
+                set_vis(self, hir_id);
+            }
+            if let Some(exports) = self.tcx.module_exports(module_def_id) {
+                for export in exports {
+                    if export.vis.is_accessible_from(defining_mod, self.tcx) {
+                        if let Res::Def(def_kind, def_id) = export.res {
+                            let vis = def_id_visibility(self.tcx, def_id).0;
+                            if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
+                                self.update_macro_reachable_def(
+                                    hir_id,
+                                    def_kind,
+                                    vis,
+                                    defining_mod,
+                                );
+                            }
                         }
                     }
                 }
             }
+        } else if let Some(hir::Node::Item(hir::Item {
+            hir_id,
+            ..
+        })) = self.tcx.hir().get_if_local(module_def_id) { // #63164
+            // `macro` defined inside of an item is only visible inside of that item's scope.
+            set_vis(self, *hir_id);
         }
     }
 
diff --git a/src/test/ui/macros/macro-in-fn.rs b/src/test/ui/macros/macro-in-fn.rs
new file mode 100644
index 00000000000..1e46346fc01
--- /dev/null
+++ b/src/test/ui/macros/macro-in-fn.rs
@@ -0,0 +1,9 @@
+#![feature(decl_macro)]
+
+pub fn moo() {
+    pub macro ABC() {{}}
+}
+
+fn main() {
+    ABC!(); //~ ERROR cannot find macro `ABC!` in this scope
+}
diff --git a/src/test/ui/macros/macro-in-fn.stderr b/src/test/ui/macros/macro-in-fn.stderr
new file mode 100644
index 00000000000..0c35fe65aa2
--- /dev/null
+++ b/src/test/ui/macros/macro-in-fn.stderr
@@ -0,0 +1,8 @@
+error: cannot find macro `ABC!` in this scope
+  --> $DIR/macro-in-fn.rs:8:5
+   |
+LL |     ABC!();
+   |     ^^^
+
+error: aborting due to previous error
+