From e0f305a6bf710f64f789f909da93a8c362823b67 Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Sat, 7 Sep 2019 00:55:58 +0800 Subject: Support textual scoped macros --- crates/ra_hir/src/nameres.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crates/ra_hir/src/nameres.rs') diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 7de422128..e6bf0e90c 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -139,6 +139,7 @@ pub(crate) struct ModuleData { pub struct ModuleScope { items: FxHashMap, macros: FxHashMap, + textual_macros: FxHashMap, } static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { @@ -164,6 +165,7 @@ impl ModuleScope { _ => None, }) } + /// It resolves in module scope. Textual scoped macros are ignored here. fn get_item_or_macro(&self, name: &Name) -> Option { match (self.get(name), self.macros.get(name)) { (Some(item), _) if !item.def.is_none() => Some(Either::A(item.def)), @@ -171,6 +173,9 @@ impl ModuleScope { _ => None, } } + fn get_textual_macro(&self, name: &Name) -> Option { + self.textual_macros.get(name).copied() + } } type ItemOrMacro = Either, MacroDef>; -- cgit v1.2.3 From 26b092bd3b431559d7aafbf42882f978c0bb3dab Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Sat, 7 Sep 2019 02:44:26 +0800 Subject: Resolve textual scoped macros inside item --- crates/ra_hir/src/nameres.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir/src/nameres.rs') 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 { name: &Name, ) -> ItemOrMacro { // Resolve in: + // - textual scoped macros // - current module / scope // - extern prelude // - std prelude + let from_textual_mcro = self[module] + .scope + .get_textual_macro(name) + .map_or_else(|| Either::A(PerNs::none()), Either::B); let from_scope = self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none())); let from_extern_prelude = self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); let from_prelude = self.resolve_in_prelude(db, name); - or(from_scope, or(Either::A(from_extern_prelude), from_prelude)) + or(from_textual_mcro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude))) } fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { -- cgit v1.2.3 From c90256429bf41958ff6c7390dfd5fa25123eabb3 Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Sat, 7 Sep 2019 22:46:44 +0800 Subject: Replace with immutable map to avoid heavy cloning --- crates/ra_hir/src/nameres.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir/src/nameres.rs') diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index befbb2a9b..7e5138d05 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -54,6 +54,7 @@ mod mod_resolution; #[cfg(test)] mod tests; +use std::hash::BuildHasherDefault; use std::sync::Arc; use once_cell::sync::Lazy; @@ -61,7 +62,7 @@ use ra_arena::{impl_arena_id, Arena, RawId}; use ra_db::{Edition, FileId}; use ra_prof::profile; use ra_syntax::ast; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; use test_utils::tested_by; use crate::{ @@ -73,6 +74,8 @@ use crate::{ AstId, BuiltinType, Crate, HirFileId, MacroDef, Module, ModuleDef, Name, Path, PathKind, Trait, }; +pub(crate) type ImmFxHashMap = im::HashMap>; + pub(crate) use self::raw::{ImportSourceMap, RawItems}; pub use self::{ @@ -139,7 +142,7 @@ pub(crate) struct ModuleData { pub struct ModuleScope { items: FxHashMap, macros: FxHashMap, - textual_macros: FxHashMap, + textual_macros: ImmFxHashMap, } static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { -- cgit v1.2.3 From f7f7c2aff80f0870f0d71bf70075e3b5bf68994f Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Sun, 8 Sep 2019 00:05:58 +0800 Subject: Revert "Replace with immutable map to avoid heavy cloning" This reverts commit 2c494eb803c88ef5d23607c3b156fce60c2b8076. See: https://github.com/rust-analyzer/rust-analyzer/pull/1784#issuecomment-529119924 --- crates/ra_hir/src/nameres.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src/nameres.rs') diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 7e5138d05..befbb2a9b 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -54,7 +54,6 @@ mod mod_resolution; #[cfg(test)] mod tests; -use std::hash::BuildHasherDefault; use std::sync::Arc; use once_cell::sync::Lazy; @@ -62,7 +61,7 @@ use ra_arena::{impl_arena_id, Arena, RawId}; use ra_db::{Edition, FileId}; use ra_prof::profile; use ra_syntax::ast; -use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use rustc_hash::{FxHashMap, FxHashSet}; use test_utils::tested_by; use crate::{ @@ -74,8 +73,6 @@ use crate::{ AstId, BuiltinType, Crate, HirFileId, MacroDef, Module, ModuleDef, Name, Path, PathKind, Trait, }; -pub(crate) type ImmFxHashMap = im::HashMap>; - pub(crate) use self::raw::{ImportSourceMap, RawItems}; pub use self::{ @@ -142,7 +139,7 @@ pub(crate) struct ModuleData { pub struct ModuleScope { items: FxHashMap, macros: FxHashMap, - textual_macros: ImmFxHashMap, + textual_macros: FxHashMap, } static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { -- cgit v1.2.3 From 92c07803cc0ce1d2008cc912f006d1cd66ff3f4a Mon Sep 17 00:00:00 2001 From: uHOOCCOOHu Date: Sun, 8 Sep 2019 00:37:54 +0800 Subject: Rename `textual_macro` -> `legacy_macro` Add comments --- crates/ra_hir/src/nameres.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir/src/nameres.rs') diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index befbb2a9b..74546e5e2 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -138,8 +138,21 @@ pub(crate) struct ModuleData { #[derive(Debug, Default, PartialEq, Eq, Clone)] pub struct ModuleScope { items: FxHashMap, + /// Macros in current module scoped + /// + /// This scope works exactly the same way that item scoping does. + /// Macro invocation with quantified path will search in it. + /// See details below. macros: FxHashMap, - textual_macros: FxHashMap, + /// Macros visable in current module in legacy textual scope + /// + /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first. + /// If it yields no result, then it turns to module scoped `macros`. + /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped, + /// and only normal scoped `macros` will be searched in. + /// + /// Note that this automatically inherit macros defined textually before the definition of module itself. + legacy_macros: FxHashMap, } static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { @@ -173,8 +186,8 @@ impl ModuleScope { _ => None, } } - fn get_textual_macro(&self, name: &Name) -> Option { - self.textual_macros.get(name).copied() + fn get_legacy_macro(&self, name: &Name) -> Option { + self.legacy_macros.get(name).copied() } } @@ -489,13 +502,13 @@ impl CrateDefMap { name: &Name, ) -> ItemOrMacro { // Resolve in: - // - textual scoped macros + // - legacy scope // - current module / scope // - extern prelude // - std prelude - let from_textual_mcro = self[module] + let from_legacy_macro = self[module] .scope - .get_textual_macro(name) + .get_legacy_macro(name) .map_or_else(|| Either::A(PerNs::none()), Either::B); let from_scope = self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none())); @@ -503,7 +516,7 @@ impl CrateDefMap { self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); let from_prelude = self.resolve_in_prelude(db, name); - or(from_textual_mcro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude))) + or(from_legacy_macro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude))) } fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { -- cgit v1.2.3