diff options
author | uHOOCCOOHu <[email protected]> | 2019-09-06 19:44:26 +0100 |
---|---|---|
committer | uHOOCCOOHu <[email protected]> | 2019-09-08 18:34:53 +0100 |
commit | 26b092bd3b431559d7aafbf42882f978c0bb3dab (patch) | |
tree | 194c41ab1320730d7f08823127404056e235cf2e /crates/ra_hir/src/nameres | |
parent | e0f305a6bf710f64f789f909da93a8c362823b67 (diff) |
Resolve textual scoped macros inside item
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/macros.rs | 16 |
2 files changed, 24 insertions, 8 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index f897547e3..10c32ffa1 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -14,8 +14,8 @@ use crate::{ | |||
14 | raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData, ModuleDef, PerNs, | 14 | raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData, ModuleDef, PerNs, |
15 | ReachedFixedPoint, Resolution, ResolveMode, | 15 | ReachedFixedPoint, Resolution, ResolveMode, |
16 | }, | 16 | }, |
17 | AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, Static, Struct, Trait, | 17 | AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, |
18 | TypeAlias, Union, | 18 | Struct, Trait, TypeAlias, Union, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 21 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -156,9 +156,6 @@ where | |||
156 | /// the definition of current module. | 156 | /// the definition of current module. |
157 | /// And also, `macro_use` on a module will import all textual macros visable inside to | 157 | /// And also, `macro_use` on a module will import all textual macros visable inside to |
158 | /// current textual scope, with possible shadowing. | 158 | /// current textual scope, with possible shadowing. |
159 | /// | ||
160 | /// In a single module, the order of definition/usage of textual scoped macros matters. | ||
161 | /// But we ignore it here to make it easy to implement. | ||
162 | fn define_textual_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) { | 159 | fn define_textual_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) { |
163 | // Always shadowing | 160 | // Always shadowing |
164 | self.def_map.modules[module_id] | 161 | self.def_map.modules[module_id] |
@@ -700,8 +697,13 @@ where | |||
700 | return; | 697 | return; |
701 | } | 698 | } |
702 | 699 | ||
703 | // Case 3: path to a macro from another crate, expand during name resolution | 700 | // Case 3: resolve in module scope, expand during name resolution. |
704 | self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone())) | 701 | // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. |
702 | let mut path = mac.path.clone(); | ||
703 | if path.is_ident() { | ||
704 | path.kind = PathKind::Self_; | ||
705 | } | ||
706 | self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path)); | ||
705 | } | 707 | } |
706 | 708 | ||
707 | fn import_all_textual_macros(&mut self, module_id: CrateModuleId) { | 709 | fn import_all_textual_macros(&mut self, module_id: CrateModuleId) { |
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs index 8f0db95f2..a894c6836 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir/src/nameres/tests/macros.rs | |||
@@ -279,7 +279,7 @@ fn prelude_cycle() { | |||
279 | } | 279 | } |
280 | 280 | ||
281 | #[test] | 281 | #[test] |
282 | fn plain_macros_are_textual_scoped_between_modules() { | 282 | fn plain_macros_are_textual_scoped() { |
283 | let map = def_map( | 283 | let map = def_map( |
284 | r#" | 284 | r#" |
285 | //- /main.rs | 285 | //- /main.rs |
@@ -310,6 +310,15 @@ fn plain_macros_are_textual_scoped_between_modules() { | |||
310 | } | 310 | } |
311 | foo!(ok_double_macro_use_shadow); | 311 | foo!(ok_double_macro_use_shadow); |
312 | 312 | ||
313 | baz!(NotFoundBefore); | ||
314 | #[macro_use] | ||
315 | mod m7 { | ||
316 | macro_rules! baz { | ||
317 | ($x:ident) => { struct $x; } | ||
318 | } | ||
319 | } | ||
320 | baz!(OkAfter); | ||
321 | |||
313 | //- /m1.rs | 322 | //- /m1.rs |
314 | foo!(NotFoundBeforeInside1); | 323 | foo!(NotFoundBeforeInside1); |
315 | macro_rules! bar { | 324 | macro_rules! bar { |
@@ -337,14 +346,19 @@ fn plain_macros_are_textual_scoped_between_modules() { | |||
337 | assert_snapshot!(map, @r###" | 346 | assert_snapshot!(map, @r###" |
338 | ⋮crate | 347 | ⋮crate |
339 | ⋮Ok: t v | 348 | ⋮Ok: t v |
349 | ⋮OkAfter: t v | ||
340 | ⋮OkShadowStop: t v | 350 | ⋮OkShadowStop: t v |
341 | ⋮foo: m | 351 | ⋮foo: m |
342 | ⋮m1: t | 352 | ⋮m1: t |
343 | ⋮m2: t | 353 | ⋮m2: t |
344 | ⋮m3: t | 354 | ⋮m3: t |
345 | ⋮m5: t | 355 | ⋮m5: t |
356 | ⋮m7: t | ||
346 | ⋮ok_double_macro_use_shadow: v | 357 | ⋮ok_double_macro_use_shadow: v |
347 | ⋮ | 358 | ⋮ |
359 | ⋮crate::m7 | ||
360 | ⋮baz: m | ||
361 | ⋮ | ||
348 | ⋮crate::m1 | 362 | ⋮crate::m1 |
349 | ⋮bar: m | 363 | ⋮bar: m |
350 | ⋮ | 364 | ⋮ |