diff options
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/macros.rs | 37 |
3 files changed, 63 insertions, 5 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 98c74fe25..bf3968bd6 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -204,6 +204,7 @@ impl DefCollector<'_> { | |||
204 | ast_id: None, | 204 | ast_id: None, |
205 | krate: Some(krate), | 205 | krate: Some(krate), |
206 | kind: MacroDefKind::CustomDerive(expander), | 206 | kind: MacroDefKind::CustomDerive(expander), |
207 | local_inner: false, | ||
207 | }; | 208 | }; |
208 | 209 | ||
209 | self.define_proc_macro(name.clone(), macro_id); | 210 | self.define_proc_macro(name.clone(), macro_id); |
@@ -941,6 +942,7 @@ impl ModCollector<'_, '_> { | |||
941 | ast_id: Some(ast_id.ast_id), | 942 | ast_id: Some(ast_id.ast_id), |
942 | krate: Some(self.def_collector.def_map.krate), | 943 | krate: Some(self.def_collector.def_map.krate), |
943 | kind: MacroDefKind::Declarative, | 944 | kind: MacroDefKind::Declarative, |
945 | local_inner: mac.local_inner, | ||
944 | }; | 946 | }; |
945 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); | 947 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); |
946 | } | 948 | } |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 39b011ad7..a71503c76 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -188,6 +188,7 @@ pub(super) struct MacroData { | |||
188 | pub(super) path: ModPath, | 188 | pub(super) path: ModPath, |
189 | pub(super) name: Option<Name>, | 189 | pub(super) name: Option<Name>, |
190 | pub(super) export: bool, | 190 | pub(super) export: bool, |
191 | pub(super) local_inner: bool, | ||
191 | pub(super) builtin: bool, | 192 | pub(super) builtin: bool, |
192 | } | 193 | } |
193 | 194 | ||
@@ -401,14 +402,32 @@ impl RawItemsCollector { | |||
401 | 402 | ||
402 | let name = m.name().map(|it| it.as_name()); | 403 | let name = m.name().map(|it| it.as_name()); |
403 | let ast_id = self.source_ast_id_map.ast_id(&m); | 404 | let ast_id = self.source_ast_id_map.ast_id(&m); |
404 | // FIXME: cfg_attr | ||
405 | let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); | ||
406 | 405 | ||
407 | // FIXME: cfg_attr | 406 | // FIXME: cfg_attr |
408 | let builtin = | 407 | let export_attr = attrs.by_key("macro_export"); |
409 | m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "rustc_builtin_macro"); | 408 | |
409 | let export = export_attr.exists(); | ||
410 | let local_inner = if export { | ||
411 | export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { | ||
412 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { | ||
413 | ident.text.contains("local_inner_macros") | ||
414 | } | ||
415 | _ => false, | ||
416 | }) | ||
417 | } else { | ||
418 | false | ||
419 | }; | ||
420 | |||
421 | let builtin = attrs.by_key("rustc_builtin_macro").exists(); | ||
410 | 422 | ||
411 | let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export, builtin }); | 423 | let m = self.raw_items.macros.alloc(MacroData { |
424 | ast_id, | ||
425 | path, | ||
426 | name, | ||
427 | export, | ||
428 | local_inner, | ||
429 | builtin, | ||
430 | }); | ||
412 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); | 431 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); |
413 | } | 432 | } |
414 | 433 | ||
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index b0befdfbd..9bc0e6287 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs | |||
@@ -136,6 +136,43 @@ fn macro_rules_export_with_local_inner_macros_are_visible() { | |||
136 | } | 136 | } |
137 | 137 | ||
138 | #[test] | 138 | #[test] |
139 | fn local_inner_macros_makes_local_macros_usable() { | ||
140 | let map = def_map( | ||
141 | " | ||
142 | //- /main.rs crate:main deps:foo | ||
143 | foo::structs!(Foo, Bar); | ||
144 | mod bar; | ||
145 | //- /bar.rs | ||
146 | use crate::*; | ||
147 | //- /lib.rs crate:foo | ||
148 | #[macro_export(local_inner_macros)] | ||
149 | macro_rules! structs { | ||
150 | ($($i:ident),*) => { | ||
151 | inner!($($i),*); | ||
152 | } | ||
153 | } | ||
154 | #[macro_export] | ||
155 | macro_rules! inner { | ||
156 | ($($i:ident),*) => { | ||
157 | $(struct $i { field: u32 } )* | ||
158 | } | ||
159 | } | ||
160 | ", | ||
161 | ); | ||
162 | assert_snapshot!(map, @r###" | ||
163 | ⋮crate | ||
164 | ⋮Bar: t v | ||
165 | ⋮Foo: t v | ||
166 | ⋮bar: t | ||
167 | ⋮ | ||
168 | ⋮crate::bar | ||
169 | ⋮Bar: t v | ||
170 | ⋮Foo: t v | ||
171 | ⋮bar: t | ||
172 | "###); | ||
173 | } | ||
174 | |||
175 | #[test] | ||
139 | fn unexpanded_macro_should_expand_by_fixedpoint_loop() { | 176 | fn unexpanded_macro_should_expand_by_fixedpoint_loop() { |
140 | let map = def_map( | 177 | let map = def_map( |
141 | " | 178 | " |