about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-08-21 12:22:15 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-08-21 13:50:05 +0200
commit3f89eebd20955edf89477f72e99fbf9ab0efc936 (patch)
tree76525d527bedbb032aa4f04716fc4d535aea8999
parenta7d15a8c3b5e9bd651d2a2606e3bd346e2b3b2d1 (diff)
downloadrust-3f89eebd20955edf89477f72e99fbf9ab0efc936.tar.gz
rust-3f89eebd20955edf89477f72e99fbf9ab0efc936.zip
internal: Implement `module_path` macro
-rw-r--r--src/tools/rust-analyzer/crates/base-db/src/input.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expander.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/lib.rs44
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs15
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres.rs28
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs27
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs30
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/eager.rs45
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs25
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs65
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/status.rs1
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs2
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/minicore.rs11
20 files changed, 279 insertions, 71 deletions
diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs
index 3616fa9fd86..b67f4c7a0cc 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/input.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs
@@ -272,6 +272,7 @@ impl ReleaseChannel {
     }
 }
 
+#[non_exhaustive]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct CrateData {
     pub root_file_id: FileId,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index d17ebd7ff92..c62f2f87338 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -748,8 +748,9 @@ impl<'a> AssocItemCollector<'a> {
                     &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
                     ctxt,
                     expand_to,
-                    self.expander.krate(),
+                    self.expander.module,
                     resolver,
+                    |module| module.def_map(self.db).path_for_module(self.db, module),
                 ) {
                     Ok(Some(call_id)) => {
                         let res =
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs
index 6d8b4445f75..57bd54ed17c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs
@@ -69,9 +69,12 @@ impl Expander {
 
         let result = self.within_limit(db, |this| {
             let macro_call = this.in_file(&macro_call);
-            match macro_call.as_call_id_with_errors(db.upcast(), this.module.krate(), |path| {
-                resolver(path).map(|it| db.macro_def(it))
-            }) {
+            match macro_call.as_call_id(
+                db.upcast(),
+                this.module,
+                |path| resolver(path).map(|it| db.macro_def(it)),
+                |module| this.module.def_map(db).path_for_module(db, module),
+            ) {
                 Ok(call_id) => call_id,
                 Err(resolve_err) => {
                     unresolved_macro_err = Some(resolve_err);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index 4ced30c81dc..40ead05b905 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -77,7 +77,7 @@ use base_db::{
 use hir_expand::{
     builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
     db::ExpandDatabase,
-    eager::expand_eager_macro_input,
+    eager::{expand_eager_macro_input, expand_module_path_as_eager},
     impl_intern_lookup,
     name::Name,
     proc_macro::{CustomProcMacroExpander, ProcMacroKind},
@@ -1400,26 +1400,19 @@ pub trait AsMacroCall {
     fn as_call_id(
         &self,
         db: &dyn ExpandDatabase,
-        krate: CrateId,
-        resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
-    ) -> Option<MacroCallId> {
-        self.as_call_id_with_errors(db, krate, resolver).ok()?.value
-    }
-
-    fn as_call_id_with_errors(
-        &self,
-        db: &dyn ExpandDatabase,
-        krate: CrateId,
+        module: ModuleId,
         resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
+        mod_path: impl FnOnce(ModuleId) -> String,
     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
 }
 
 impl AsMacroCall for InFile<&ast::MacroCall> {
-    fn as_call_id_with_errors(
+    fn as_call_id(
         &self,
         db: &dyn ExpandDatabase,
-        krate: CrateId,
+        module: ModuleId,
         resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
+        mod_path: impl FnOnce(ModuleId) -> String,
     ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
         let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
         let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
@@ -1446,9 +1439,10 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
             &path,
             call_site.ctx,
             expands_to,
-            krate,
+            module,
             resolver,
             resolver,
+            mod_path,
         )
     }
 }
@@ -1475,8 +1469,9 @@ fn macro_call_as_call_id(
     call: &AstIdWithPath<ast::MacroCall>,
     call_site: SyntaxContextId,
     expand_to: ExpandTo,
-    krate: CrateId,
+    module: ModuleId,
     resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
+    mod_path: impl FnOnce(ModuleId) -> String,
 ) -> Result<Option<MacroCallId>, UnresolvedMacro> {
     macro_call_as_call_id_with_eager(
         db,
@@ -1484,9 +1479,10 @@ fn macro_call_as_call_id(
         &call.path,
         call_site,
         expand_to,
-        krate,
+        module,
         resolver,
         resolver,
+        mod_path,
     )
     .map(|res| res.value)
 }
@@ -1497,16 +1493,26 @@ fn macro_call_as_call_id_with_eager(
     path: &path::ModPath,
     call_site: SyntaxContextId,
     expand_to: ExpandTo,
-    krate: CrateId,
+    module: ModuleId,
     resolver: impl FnOnce(&path::ModPath) -> Option<MacroDefId>,
     eager_resolver: impl Fn(&path::ModPath) -> Option<MacroDefId>,
+    mod_path: impl FnOnce(ModuleId) -> String,
 ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
     let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
 
     let res = match def.kind {
+        MacroDefKind::BuiltInEager(_, EagerExpander::ModulePath) => expand_module_path_as_eager(
+            db,
+            module.krate,
+            mod_path(module),
+            &ast_id.to_node(db),
+            ast_id,
+            def,
+            call_site,
+        ),
         MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
             db,
-            krate,
+            module.krate,
             &ast_id.to_node(db),
             ast_id,
             def,
@@ -1516,7 +1522,7 @@ fn macro_call_as_call_id_with_eager(
         _ if def.is_fn_like() => ExpandResult {
             value: Some(def.make_call(
                 db,
-                krate,
+                module.krate,
                 MacroCallKind::FnLike { ast_id, expand_to, eager: None },
                 call_site,
             )),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7f761192517..0d232deb2ce 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -95,11 +95,16 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
     for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
         let macro_call = InFile::new(source.file_id, &macro_call);
         let res = macro_call
-            .as_call_id_with_errors(&db, krate, |path| {
-                resolver
-                    .resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
-                    .map(|(it, _)| db.macro_def(it))
-            })
+            .as_call_id(
+                &db,
+                resolver.module(),
+                |path| {
+                    resolver
+                        .resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
+                        .map(|(it, _)| db.macro_def(it))
+                },
+                |module| def_map.path_for_module(&db, module),
+            )
             .unwrap();
         let macro_call_id = res.value.unwrap();
         let macro_file = MacroFileId { macro_call_id };
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 11601c683e1..cd8db00c8b2 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -63,7 +63,7 @@ use base_db::CrateId;
 use hir_expand::{
     name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
 };
-use intern::Symbol;
+use intern::{sym, Symbol};
 use itertools::Itertools;
 use la_arena::Arena;
 use rustc_hash::{FxHashMap, FxHashSet};
@@ -139,6 +139,7 @@ pub struct DefMap {
 /// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct DefMapCrateData {
+    crate_name: Option<Symbol>,
     /// The extern prelude which contains all root modules of external crates that are in scope.
     extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
 
@@ -164,6 +165,7 @@ struct DefMapCrateData {
 impl DefMapCrateData {
     fn new(edition: Edition) -> Self {
         Self {
+            crate_name: None,
             extern_prelude: FxIndexMap::default(),
             exported_derives: FxHashMap::default(),
             fn_proc_macro_mapping: FxHashMap::default(),
@@ -186,6 +188,7 @@ impl DefMapCrateData {
             registered_attrs,
             registered_tools,
             unstable_features,
+            crate_name: _,
             rustc_coherence_is_core: _,
             no_core: _,
             no_std: _,
@@ -443,6 +446,29 @@ impl DefMap {
         self.modules.iter()
     }
 
+    pub fn path_for_module(&self, db: &dyn DefDatabase, mut module: ModuleId) -> String {
+        debug_assert!(module.krate == self.krate && module.block == self.block.map(|b| b.block));
+        let mut parts = vec![];
+        if let Some(name) = module.name(db) {
+            parts.push(name.symbol().clone());
+        }
+        while let Some(parent) = module.def_map(db).containing_module(module.local_id) {
+            module = parent;
+            if let Some(name) = module.name(db) {
+                parts.push(name.symbol().clone());
+            }
+            if parts.len() > 10 {
+                break;
+            }
+        }
+        // FIXME: crate_name should be non-optional but we don't pass the name through yet
+        parts.push(match &self.data.crate_name {
+            Some(name) => name.clone(),
+            None => sym::crate_.clone(),
+        });
+        parts.into_iter().rev().format("::").to_string()
+    }
+
     pub fn derive_helpers_in_scope(
         &self,
         id: AstId<ast::Adt>,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index 22eb5a174d3..30df6c206df 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -247,18 +247,23 @@ impl DefCollector<'_> {
         let _p = tracing::info_span!("seed_with_top_level").entered();
 
         let crate_graph = self.db.crate_graph();
+        let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
+        crate_data.crate_name = crate_graph[self.def_map.krate]
+            .display_name
+            .as_ref()
+            .map(|it| it.crate_name().symbol().clone());
+
         let file_id = crate_graph[self.def_map.krate].root_file_id();
         let item_tree = self.db.file_item_tree(file_id.into());
         let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
-        let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
 
-        let mut process = true;
+        let mut crate_cged_out = false;
 
         // Process other crate-level attributes.
         for attr in &*attrs {
             if let Some(cfg) = attr.cfg() {
                 if self.cfg_options.check(&cfg) == Some(false) {
-                    process = false;
+                    crate_cged_out = true;
                     break;
                 }
             }
@@ -272,6 +277,11 @@ impl DefCollector<'_> {
                         }
                     }
                 }
+                () if *attr_name == sym::crate_name.clone() => {
+                    if let Some(name) = attr.string_value().cloned() {
+                        crate_data.crate_name = Some(name);
+                    }
+                }
                 () if *attr_name == sym::crate_type.clone() => {
                     if attr.string_value() == Some(&sym::proc_dash_macro) {
                         self.is_proc_macro = true;
@@ -337,7 +347,7 @@ impl DefCollector<'_> {
 
         self.inject_prelude();
 
-        if !process {
+        if crate_cged_out {
             return;
         }
 
@@ -1207,8 +1217,9 @@ impl DefCollector<'_> {
                         ast_id,
                         *call_site,
                         *expand_to,
-                        self.def_map.krate,
+                        self.def_map.module_id(directive.module_id),
                         resolver_def_id,
+                        |module| self.def_map.path_for_module(self.db, module),
                     );
                     if let Ok(Some(call_id)) = call_id {
                         self.def_map.modules[directive.module_id]
@@ -1486,7 +1497,7 @@ impl DefCollector<'_> {
                         ast_id,
                         *call_site,
                         *expand_to,
-                        self.def_map.krate,
+                        self.def_map.module_id(directive.module_id),
                         |path| {
                             let resolved_res = self.def_map.resolve_path_fp_with_macro(
                                 self.db,
@@ -1498,6 +1509,7 @@ impl DefCollector<'_> {
                             );
                             resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it))
                         },
+                        |module| self.def_map.path_for_module(self.db, module),
                     );
                     if let Err(UnresolvedMacro { path }) = macro_call_as_call_id {
                         self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
@@ -2351,7 +2363,7 @@ impl ModCollector<'_, '_> {
             &ast_id.path,
             ctxt,
             expand_to,
-            self.def_collector.def_map.krate,
+            self.def_collector.def_map.module_id(self.module_id),
             |path| {
                 path.as_ident().and_then(|name| {
                     let def_map = &self.def_collector.def_map;
@@ -2381,6 +2393,7 @@ impl ModCollector<'_, '_> {
                 );
                 resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
             },
+            |module| self.def_collector.def_map.path_for_module(self.def_collector.db, module),
         ) {
             // FIXME: if there were errors, this might've been in the eager expansion from an
             // unresolved macro, so we need to push this into late macro resolution. see fixme above
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs
index 252430e4e95..7b9cb4e793c 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin.rs
@@ -1,6 +1,6 @@
 //! Builtin macros and attributes
 #[macro_use]
-mod quote;
+pub(crate) mod quote;
 
 mod attr_macro;
 mod derive_macro;
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
index 795d9b14df9..e4d09ddb3ab 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
@@ -116,7 +116,6 @@ register_builtin! {
     (column, Column) => line_expand,
     (file, File) => file_expand,
     (line, Line) => line_expand,
-    (module_path, ModulePath) => module_path_expand,
     (assert, Assert) => assert_expand,
     (stringify, Stringify) => stringify_expand,
     (llvm_asm, LlvmAsm) => asm_expand,
@@ -142,7 +141,10 @@ register_builtin! {
     (include_bytes, IncludeBytes) => include_bytes_expand,
     (include_str, IncludeStr) => include_str_expand,
     (env, Env) => env_expand,
-    (option_env, OptionEnv) => option_env_expand
+    (option_env, OptionEnv) => option_env_expand,
+    // This isn't really eager, we have no inputs, but we abuse the fact how eager macros are
+    // handled in r-a to be able to thread the module path through.
+    (module_path, ModulePath) => module_path_expand
 }
 
 fn mk_pound(span: Span) -> tt::Subtree {
@@ -157,18 +159,6 @@ fn mk_pound(span: Span) -> tt::Subtree {
     )
 }
 
-fn module_path_expand(
-    _db: &dyn ExpandDatabase,
-    _id: MacroCallId,
-    _tt: &tt::Subtree,
-    span: Span,
-) -> ExpandResult<tt::Subtree> {
-    // Just return a dummy result.
-    ExpandResult::ok(quote! {span =>
-         "module::path"
-    })
-}
-
 fn line_expand(
     _db: &dyn ExpandDatabase,
     _id: MacroCallId,
@@ -904,6 +894,18 @@ fn option_env_expand(
     ExpandResult::ok(expanded)
 }
 
+fn module_path_expand(
+    _db: &dyn ExpandDatabase,
+    _id: MacroCallId,
+    tt: &tt::Subtree,
+    span: Span,
+) -> ExpandResult<tt::Subtree> {
+    // Note: The actual implementation of this is in crates\hir-expand\src\eager.rs
+    ExpandResult::ok(quote! {span =>
+         #tt
+    })
+}
+
 fn quote_expand(
     _db: &dyn ExpandDatabase,
     _arg_id: MacroCallId,
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs
index 5c33f817f9e..0c895056c22 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/quote.rs
@@ -128,7 +128,7 @@ macro_rules! quote_impl__ {
         }
     };
 }
-pub(super) use quote_impl__ as __quote;
+pub(crate) use quote_impl__ as __quote;
 
 /// FIXME:
 /// It probably should implement in proc-macro
@@ -137,7 +137,7 @@ macro_rules! quote_impl {
         $crate::builtin::quote::IntoTt::to_subtree($crate::builtin::quote::__quote!($span $($tt)*), $span)
     }
 }
-pub(super) use quote_impl as quote;
+pub(crate) use quote_impl as quote;
 
 pub(crate) trait IntoTt {
     fn to_subtree(self, span: Span) -> crate::tt::Subtree;
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs
index 1dadfe2ba99..534d5663860 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/eager.rs
@@ -32,6 +32,51 @@ use crate::{
     MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
 };
 
+pub fn expand_module_path_as_eager(
+    db: &dyn ExpandDatabase,
+    krate: CrateId,
+    mod_path: String,
+    macro_call: &ast::MacroCall,
+    ast_id: AstId<ast::MacroCall>,
+    def: MacroDefId,
+    call_site: SyntaxContextId,
+) -> ExpandResult<Option<MacroCallId>> {
+    let expand_to = ExpandTo::from_call_site(macro_call);
+
+    // Note:
+    // When `lazy_expand` is called, its *parent* file must already exist.
+    // Here we store an eager macro id for the argument expanded subtree
+    // for that purpose.
+    let arg_id = MacroCallLoc {
+        def,
+        krate,
+        kind: MacroCallKind::FnLike { ast_id, expand_to: ExpandTo::Expr, eager: None },
+        ctxt: call_site,
+    }
+    .intern(db);
+    #[allow(deprecated)] // builtin eager macros are never derives
+    let (_, _, span) = db.macro_arg(arg_id);
+    let subtree = crate::builtin::quote::quote! {span => #mod_path};
+
+    let loc = MacroCallLoc {
+        def,
+        krate,
+        kind: MacroCallKind::FnLike {
+            ast_id,
+            expand_to,
+            eager: Some(Arc::new(EagerCallInfo {
+                arg: Arc::new(subtree),
+                arg_id,
+                error: None,
+                span,
+            })),
+        },
+        ctxt: call_site,
+    };
+
+    ExpandResult { value: Some(loc.intern(db)), err: None }
+}
+
 pub fn expand_eager_macro_input(
     db: &dyn ExpandDatabase,
     krate: CrateId,
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index d086aee4285..d9f3b9e9433 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -364,7 +364,6 @@ impl<'db> SemanticsImpl<'db> {
                 _,
                 BuiltinFnLikeExpander::Column
                     | BuiltinFnLikeExpander::File
-                    | BuiltinFnLikeExpander::ModulePath
                     | BuiltinFnLikeExpander::Asm
                     | BuiltinFnLikeExpander::LlvmAsm
                     | BuiltinFnLikeExpander::GlobalAsm
@@ -482,10 +481,26 @@ impl<'db> SemanticsImpl<'db> {
         let SourceAnalyzer { file_id, resolver, .. } =
             self.analyze_no_infer(actual_macro_call.syntax())?;
         let macro_call = InFile::new(file_id, actual_macro_call);
-        let krate = resolver.krate();
-        let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
-            resolver.resolve_path_as_macro_def(self.db.upcast(), path, Some(MacroSubNs::Bang))
-        })?;
+        let macro_call_id = macro_call
+            .as_call_id(
+                self.db.upcast(),
+                resolver.module(),
+                |path| {
+                    resolver.resolve_path_as_macro_def(
+                        self.db.upcast(),
+                        path,
+                        Some(MacroSubNs::Bang),
+                    )
+                },
+                |module| {
+                    resolver
+                        .module()
+                        .def_map(self.db.upcast())
+                        .path_for_module(self.db.upcast(), module)
+                },
+            )
+            .ok()?
+            .value?;
         hir_expand::db::expand_speculative(
             self.db.upcast(),
             macro_call_id,
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index be0116862b9..fe1d5b5764d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -839,12 +839,25 @@ impl SourceAnalyzer {
         db: &dyn HirDatabase,
         macro_call: InFile<&ast::MacroCall>,
     ) -> Option<MacroFileId> {
-        let krate = self.resolver.krate();
         // FIXME: This causes us to parse, generally this is the wrong approach for resolving a
         // macro call to a macro call id!
-        let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
-            self.resolver.resolve_path_as_macro_def(db.upcast(), path, Some(MacroSubNs::Bang))
-        })?;
+        let macro_call_id = macro_call
+            .as_call_id(
+                db.upcast(),
+                self.resolver.module(),
+                |path| {
+                    self.resolver.resolve_path_as_macro_def(
+                        db.upcast(),
+                        path,
+                        Some(MacroSubNs::Bang),
+                    )
+                },
+                |module| {
+                    self.resolver.module().def_map(db.upcast()).path_for_module(db.upcast(), module)
+                },
+            )
+            .ok()?
+            .value?;
         // why the 64?
         Some(macro_call_id.as_macro_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
     }
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
index f75b8fb7d02..dbe851ec474 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_type_definition.rs
@@ -24,9 +24,11 @@ pub(crate) fn goto_type_definition(
     let file: ast::SourceFile = sema.parse_guess_edition(file_id);
     let token: SyntaxToken =
         pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind {
-            IDENT | INT_NUMBER | T![self] => 2,
-            kind if kind.is_trivia() => 0,
-            _ => 1,
+            IDENT | INT_NUMBER | T![self] => 3,
+            // operators
+            T!['('] | T!['['] | T!['{'] | T![')'] | T![']'] | T!['}'] | T![!] | T![?] => 2,
+            kind if !kind.is_trivia() => 1,
+            _ => 0,
         })?;
 
     let mut res = Vec::new();
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 8b60e562d7b..fc59307806f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -8702,3 +8702,68 @@ fn foo() {
         "#]],
     );
 }
+
+#[test]
+fn module_path_macro() {
+    check(
+        r##"
+//- minicore: module_path
+
+const C$0: &'static str = module_path!();
+"##,
+        expect![[r#"
+            *C*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            const C: &'static str = "test"
+            ```
+        "#]],
+    );
+    check(
+        r##"
+//- minicore: module_path
+
+mod foo {
+    const C$0: &'static str = module_path!();
+}
+"##,
+        expect![[r#"
+            *C*
+
+            ```rust
+            test::foo
+            ```
+
+            ```rust
+            const C: &'static str = "test::foo"
+            ```
+        "#]],
+    );
+    check(
+        r##"
+//- minicore: module_path
+mod baz {
+    const _: () = {
+        mod bar {
+            const C$0: &'static str = module_path!();
+        }
+    }
+}
+"##,
+        expect![[r#"
+            *C*
+
+            ```rust
+            test::bar
+            ```
+
+            ```rust
+            const C: &'static str = "test::baz::bar"
+            ```
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/status.rs b/src/tools/rust-analyzer/crates/ide/src/status.rs
index 67d6932da96..ce21e3cad5b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/status.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/status.rs
@@ -69,6 +69,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
                 dependencies,
                 origin,
                 is_proc_macro,
+                ..
             } = &crate_graph[crate_id];
             format_to!(
                 buf,
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index 2feca32ff86..5d05ef3b79b 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -177,6 +177,7 @@ define_symbols! {
     coroutine_state,
     coroutine,
     count,
+    crate_name,
     crate_type,
     CStr,
     debug_assertions,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
index 89fe712ced0..f2d21208d51 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs
@@ -22,7 +22,7 @@ use crate::{
 };
 
 struct LsifManager<'a> {
-    count: i32,
+    id_counter: i32,
     token_map: FxHashMap<TokenId, Id>,
     range_map: FxHashMap<FileRange, Id>,
     file_map: FxHashMap<FileId, Id>,
@@ -44,7 +44,7 @@ impl From<Id> for lsp_types::NumberOrString {
 impl LsifManager<'_> {
     fn new<'a>(analysis: &'a Analysis, db: &'a RootDatabase, vfs: &'a Vfs) -> LsifManager<'a> {
         LsifManager {
-            count: 0,
+            id_counter: 0,
             token_map: FxHashMap::default(),
             range_map: FxHashMap::default(),
             file_map: FxHashMap::default(),
@@ -56,9 +56,9 @@ impl LsifManager<'_> {
     }
 
     fn add(&mut self, data: lsif::Element) -> Id {
-        let id = Id(self.count);
+        let id = Id(self.id_counter);
         self.emit(&serde_json::to_string(&lsif::Entry { id: id.into(), data }).unwrap());
-        self.count += 1;
+        self.id_counter += 1;
         id
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
index 34b20851dd6..91d6c9f5e24 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs
@@ -49,7 +49,6 @@ impl flags::Scip {
             let error_sink;
             (config, error_sink, _) = config.apply_change(change);
 
-            // FIXME @alibektas : What happens to errors without logging?
             error!(?error_sink, "Config Error(s)");
         }
         let cargo_config = config.cargo();
@@ -116,7 +115,6 @@ impl flags::Scip {
 
             tokens.into_iter().for_each(|(text_range, id)| {
                 let token = si.tokens.get(id).unwrap();
-
                 let range = text_range_to_scip_range(&line_index, text_range);
                 let symbol = tokens_to_symbol
                     .entry(id)
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
index 2d615c34a35..2e01d199088 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -41,6 +41,7 @@
 //!     iterator: option
 //!     iterators: iterator, fn
 //!     manually_drop: drop
+//!     module_path:
 //!     non_null:
 //!     non_zero:
 //!     option: panic
@@ -1434,6 +1435,16 @@ mod panicking {
 
 #[macro_use]
 mod macros {
+    // region:module_path
+    #[macro_export]
+    #[rustc_builtin_macro]
+    macro_rules! module_path {
+        ($($arg:tt)*) => {
+            /* compiler built-in */
+        };
+    }
+    // endregion:module_path
+
     // region:panic
     #[macro_export]
     #[rustc_builtin_macro(core_panic)]