aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r--crates/hir_def/src/nameres/collector.rs19
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs41
2 files changed, 60 insertions, 0 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 28ef49488..f98a42643 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -87,6 +87,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
87 mod_dirs: FxHashMap::default(), 87 mod_dirs: FxHashMap::default(),
88 cfg_options, 88 cfg_options,
89 proc_macros, 89 proc_macros,
90 exports_proc_macros: false,
90 from_glob_import: Default::default(), 91 from_glob_import: Default::default(),
91 }; 92 };
92 collector.collect(); 93 collector.collect();
@@ -203,6 +204,7 @@ struct DefCollector<'a> {
203 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 204 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
204 cfg_options: &'a CfgOptions, 205 cfg_options: &'a CfgOptions,
205 proc_macros: Vec<(Name, ProcMacroExpander)>, 206 proc_macros: Vec<(Name, ProcMacroExpander)>,
207 exports_proc_macros: bool,
206 from_glob_import: PerNsGlobImports, 208 from_glob_import: PerNsGlobImports,
207} 209}
208 210
@@ -260,9 +262,25 @@ impl DefCollector<'_> {
260 self.record_resolved_import(directive) 262 self.record_resolved_import(directive)
261 } 263 }
262 self.unresolved_imports = unresolved_imports; 264 self.unresolved_imports = unresolved_imports;
265
266 // FIXME: This condition should instead check if this is a `proc-macro` type crate.
267 if self.exports_proc_macros {
268 // A crate exporting procedural macros is not allowed to export anything else.
269 //
270 // Additionally, while the proc macro entry points must be `pub`, they are not publicly
271 // exported in type/value namespace. This function reduces the visibility of all items
272 // in the crate root that aren't proc macros.
273 let root = self.def_map.root;
274 let root = &mut self.def_map.modules[root];
275 root.scope.censor_non_proc_macros(ModuleId {
276 krate: self.def_map.krate,
277 local_id: self.def_map.root,
278 });
279 }
263 } 280 }
264 281
265 fn resolve_proc_macro(&mut self, name: &Name) { 282 fn resolve_proc_macro(&mut self, name: &Name) {
283 self.exports_proc_macros = true;
266 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { 284 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
267 Some((_, expander)) => MacroDefId { 285 Some((_, expander)) => MacroDefId {
268 ast_id: None, 286 ast_id: None,
@@ -1310,6 +1328,7 @@ mod tests {
1310 mod_dirs: FxHashMap::default(), 1328 mod_dirs: FxHashMap::default(),
1311 cfg_options: &CfgOptions::default(), 1329 cfg_options: &CfgOptions::default(),
1312 proc_macros: Default::default(), 1330 proc_macros: Default::default(),
1331 exports_proc_macros: false,
1313 from_glob_import: Default::default(), 1332 from_glob_import: Default::default(),
1314 }; 1333 };
1315 collector.collect(); 1334 collector.collect();
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index 98cb5a0fd..0851c3b7d 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -699,3 +699,44 @@ fn resolves_proc_macros() {
699 "#]], 699 "#]],
700 ); 700 );
701} 701}
702
703#[test]
704fn proc_macro_censoring() {
705 // Make sure that only proc macros are publicly exported from proc-macro crates.
706
707 check(
708 r"
709 //- /main.rs crate:main deps:macros
710 pub use macros::*;
711
712 //- /macros.rs crate:macros
713 pub struct TokenStream;
714
715 #[proc_macro]
716 pub fn function_like_macro(args: TokenStream) -> TokenStream {
717 args
718 }
719
720 #[proc_macro_attribute]
721 pub fn attribute_macro(_args: TokenStream, item: TokenStream) -> TokenStream {
722 item
723 }
724
725 #[proc_macro_derive(DummyTrait)]
726 pub fn derive_macro(_item: TokenStream) -> TokenStream {
727 TokenStream
728 }
729
730 #[macro_export]
731 macro_rules! mbe {
732 () => {};
733 }
734 ",
735 expect![[r#"
736 crate
737 DummyTrait: m
738 attribute_macro: m
739 function_like_macro: m
740 "#]],
741 );
742}