Skip to content

Commit 8c07d78

Browse files
committed
When declaring a declarative macro in an item it's only accessible inside it
1 parent 7b0085a commit 8c07d78

File tree

4 files changed

+58
-32
lines changed

4 files changed

+58
-32
lines changed

src/librustc/hir/map/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,18 +514,21 @@ impl<'hir> Map<'hir> {
514514
&self.forest.krate.attrs
515515
}
516516

517-
pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId)
518-
{
517+
pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
518+
self.get_if_module(module).expect("not a module")
519+
}
520+
521+
pub fn get_if_module(&self, module: DefId) -> Option<(&'hir Mod, Span, HirId)> {
519522
let hir_id = self.as_local_hir_id(module).unwrap();
520523
self.read(hir_id);
521524
match self.find_entry(hir_id).unwrap().node {
522525
Node::Item(&Item {
523526
span,
524527
node: ItemKind::Mod(ref m),
525528
..
526-
}) => (m, span, hir_id),
527-
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
528-
_ => panic!("not a module")
529+
}) => Some((m, span, hir_id)),
530+
Node::Crate => Some((&self.forest.krate.module, self.forest.krate.span, hir_id)),
531+
_ => None,
529532
}
530533
}
531534

src/librustc_privacy/lib.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -508,39 +508,45 @@ impl EmbargoVisitor<'tcx> {
508508
}
509509
}
510510

511-
fn update_macro_reachable_mod(
512-
&mut self,
513-
reachable_mod: hir::HirId,
514-
defining_mod: DefId,
515-
) {
516-
let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
517-
let module = self.tcx.hir().get_module(module_def_id).0;
518-
for item_id in &module.item_ids {
519-
let hir_id = item_id.id;
520-
let item_def_id = self.tcx.hir().local_def_id(hir_id);
521-
if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
522-
let item = self.tcx.hir().expect_item(hir_id);
523-
let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
524-
self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
511+
fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) {
512+
let set_vis = |this: &mut Self, hir_id: hir::HirId| {
513+
let item_def_id = this.tcx.hir().local_def_id(hir_id);
514+
if let Some(def_kind) = this.tcx.def_kind(item_def_id) {
515+
let item = this.tcx.hir().expect_item(hir_id);
516+
let vis = ty::Visibility::from_hir(&item.vis, hir_id, this.tcx);
517+
this.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
525518
}
526-
}
519+
};
527520

528-
if let Some(exports) = self.tcx.module_exports(module_def_id) {
529-
for export in exports {
530-
if export.vis.is_accessible_from(defining_mod, self.tcx) {
531-
if let Res::Def(def_kind, def_id) = export.res {
532-
let vis = def_id_visibility(self.tcx, def_id).0;
533-
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
534-
self.update_macro_reachable_def(
535-
hir_id,
536-
def_kind,
537-
vis,
538-
defining_mod,
539-
);
521+
let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
522+
if let Some((module, _, _)) = self.tcx.hir().get_if_module(module_def_id) {
523+
for item_id in &module.item_ids {
524+
let hir_id = item_id.id;
525+
set_vis(self, hir_id);
526+
}
527+
if let Some(exports) = self.tcx.module_exports(module_def_id) {
528+
for export in exports {
529+
if export.vis.is_accessible_from(defining_mod, self.tcx) {
530+
if let Res::Def(def_kind, def_id) = export.res {
531+
let vis = def_id_visibility(self.tcx, def_id).0;
532+
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
533+
self.update_macro_reachable_def(
534+
hir_id,
535+
def_kind,
536+
vis,
537+
defining_mod,
538+
);
539+
}
540540
}
541541
}
542542
}
543543
}
544+
} else if let Some(hir::Node::Item(hir::Item {
545+
hir_id,
546+
..
547+
})) = self.tcx.hir().get_if_local(module_def_id) { // #63164
548+
// `macro` defined inside of an item is only visible inside of that item's scope.
549+
set_vis(self, *hir_id);
544550
}
545551
}
546552

src/test/ui/macros/macro-in-fn.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(decl_macro)]
2+
3+
pub fn moo() {
4+
pub macro ABC() {{}}
5+
}
6+
7+
fn main() {
8+
ABC!(); //~ ERROR cannot find macro `ABC!` in this scope
9+
}

src/test/ui/macros/macro-in-fn.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: cannot find macro `ABC!` in this scope
2+
--> $DIR/macro-in-fn.rs:8:5
3+
|
4+
LL | ABC!();
5+
| ^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)