aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/nameres.rs7
-rw-r--r--crates/ra_hir/src/nameres/collector.rs16
-rw-r--r--crates/ra_hir/src/nameres/tests/macros.rs16
-rw-r--r--crates/ra_hir/src/ty/tests.rs35
4 files changed, 65 insertions, 9 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index e6bf0e90c..befbb2a9b 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -489,16 +489,21 @@ impl CrateDefMap {
489 name: &Name, 489 name: &Name,
490 ) -> ItemOrMacro { 490 ) -> ItemOrMacro {
491 // Resolve in: 491 // Resolve in:
492 // - textual scoped macros
492 // - current module / scope 493 // - current module / scope
493 // - extern prelude 494 // - extern prelude
494 // - std prelude 495 // - std prelude
496 let from_textual_mcro = self[module]
497 .scope
498 .get_textual_macro(name)
499 .map_or_else(|| Either::A(PerNs::none()), Either::B);
495 let from_scope = 500 let from_scope =
496 self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none())); 501 self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none()));
497 let from_extern_prelude = 502 let from_extern_prelude =
498 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 503 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
499 let from_prelude = self.resolve_in_prelude(db, name); 504 let from_prelude = self.resolve_in_prelude(db, name);
500 505
501 or(from_scope, or(Either::A(from_extern_prelude), from_prelude)) 506 or(from_textual_mcro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude)))
502 } 507 }
503 508
504 fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> { 509 fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> {
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
21pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 21pub(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]
282fn plain_macros_are_textual_scoped_between_modules() { 282fn 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
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index c4bddde85..f2d5b115e 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2803,6 +2803,41 @@ fn main() {
2803 ); 2803 );
2804} 2804}
2805 2805
2806#[test]
2807fn infer_textual_scoped_macros_expanded() {
2808 assert_snapshot!(
2809 infer(r#"
2810struct Foo(Vec<i32>);
2811
2812#[macro_use]
2813mod m {
2814 macro_rules! foo {
2815 ($($item:expr),*) => {
2816 {
2817 Foo(vec![$($item,)*])
2818 }
2819 };
2820 }
2821}
2822
2823fn main() {
2824 let x = foo!(1,2);
2825 let y = crate::foo!(1,2);
2826}
2827"#),
2828 @r###"
2829 ![0; 17) '{Foo(v...,2,])}': Foo
2830 ![1; 4) 'Foo': Foo({unknown}) -> Foo
2831 ![1; 16) 'Foo(vec![1,2,])': Foo
2832 ![5; 15) 'vec![1,2,]': {unknown}
2833 [195; 251) '{ ...,2); }': ()
2834 [205; 206) 'x': Foo
2835 [228; 229) 'y': {unknown}
2836 [232; 248) 'crate:...!(1,2)': {unknown}
2837 "###
2838 );
2839}
2840
2806#[ignore] 2841#[ignore]
2807#[test] 2842#[test]
2808fn method_resolution_trait_before_autoref() { 2843fn method_resolution_trait_before_autoref() {