From d8a5d39c2d05fb59b6c243935111714e18334599 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 11 Jun 2020 11:30:06 +0200 Subject: Make relevant_crates return a Set --- Cargo.lock | 1 + crates/ra_db/src/input.rs | 8 +++----- crates/ra_db/src/lib.rs | 20 +++++++++++++------- crates/ra_hir_def/src/test_db.rs | 3 ++- crates/ra_hir_expand/Cargo.toml | 1 + crates/ra_hir_expand/src/builtin_derive.rs | 7 +++---- crates/ra_hir_expand/src/builtin_macro.rs | 5 ++--- crates/ra_hir_expand/src/lib.rs | 5 +++++ crates/ra_hir_expand/src/test_db.rs | 3 ++- crates/ra_hir_ty/src/test_db.rs | 3 ++- crates/ra_ide_db/src/lib.rs | 4 ++-- 11 files changed, 36 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df79334c9..22483516a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,6 +1010,7 @@ dependencies = [ "ra_prof", "ra_syntax", "ra_tt", + "rustc-hash", "test_utils", ] diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index a8d6466ea..bf26048f2 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -15,12 +15,10 @@ use std::{ use ra_cfg::CfgOptions; use ra_syntax::SmolStr; -use rustc_hash::FxHashMap; -use rustc_hash::FxHashSet; +use ra_tt::TokenExpander; +use rustc_hash::{FxHashMap, FxHashSet}; use crate::{RelativePath, RelativePathBuf}; -use fmt::Display; -use ra_tt::TokenExpander; /// `FileId` is an integer which uniquely identifies a file. File paths are /// messy and system-dependent, so most of the code should work directly with @@ -111,7 +109,7 @@ impl CrateName { } } -impl Display for CrateName { +impl fmt::Display for CrateName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 2ab314884..80ddb6058 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -7,6 +7,7 @@ use std::{panic, sync::Arc}; use ra_prof::profile; use ra_syntax::{ast, Parse, SourceFile, TextRange, TextSize}; +use rustc_hash::FxHashSet; pub use crate::{ cancellation::Canceled, @@ -95,7 +96,7 @@ pub trait FileLoader { /// `struct StrPath(str)` for clarity some day, but it's a bit messy, so we /// get by with a `&str` for the time being. fn resolve_path(&self, anchor: FileId, path: &str) -> Option; - fn relevant_crates(&self, file_id: FileId) -> Arc>; + fn relevant_crates(&self, file_id: FileId) -> Arc>; } /// Database which stores all significant input facts: source code and project @@ -133,16 +134,21 @@ pub trait SourceDatabaseExt: SourceDatabase { #[salsa::input] fn source_root(&self, id: SourceRootId) -> Arc; - fn source_root_crates(&self, id: SourceRootId) -> Arc>; + fn source_root_crates(&self, id: SourceRootId) -> Arc>; } fn source_root_crates( db: &(impl SourceDatabaseExt + SourceDatabase), id: SourceRootId, -) -> Arc> { - let root = db.source_root(id); +) -> Arc> { let graph = db.crate_graph(); - let res = root.walk().filter_map(|it| graph.crate_id_for_crate_root(it)).collect::>(); + let res = graph + .iter() + .filter(|&krate| { + let root_file = graph[krate].root_file_id; + db.file_source_root(root_file) == id + }) + .collect::>(); Arc::new(res) } @@ -156,7 +162,7 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { fn resolve_path(&self, anchor: FileId, path: &str) -> Option { // FIXME: this *somehow* should be platform agnostic... if std::path::Path::new(path).is_absolute() { - let krate = *self.relevant_crates(anchor).get(0)?; + let krate = *self.relevant_crates(anchor).iter().next()?; let (extern_source_id, relative_file) = self.0.crate_graph()[krate].extern_source.extern_path(path.as_ref())?; @@ -175,7 +181,7 @@ impl FileLoader for FileLoaderDelegate<&'_ T> { } } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates(&self, file_id: FileId) -> Arc> { let source_root = self.0.file_source_root(file_id); self.0.source_root_crates(source_root) } diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index bcfa66ac9..4581d8745 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.rs @@ -7,6 +7,7 @@ use std::{ use hir_expand::db::AstDatabase; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, Upcast}; +use rustc_hash::FxHashSet; use crate::db::DefDatabase; @@ -59,7 +60,7 @@ impl FileLoader for TestDB { fn resolve_path(&self, anchor: FileId, path: &str) -> Option { FileLoaderDelegate(self).resolve_path(anchor, path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates(&self, file_id: FileId) -> Arc> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/ra_hir_expand/Cargo.toml b/crates/ra_hir_expand/Cargo.toml index 2cd522766..e5c9f3e99 100644 --- a/crates/ra_hir_expand/Cargo.toml +++ b/crates/ra_hir_expand/Cargo.toml @@ -10,6 +10,7 @@ doctest = false [dependencies] log = "0.4.8" either = "1.5.3" +rustc-hash = "1.0.0" ra_arena = { path = "../ra_arena" } ra_db = { path = "../ra_db" } diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index 1dc9cac66..967d1f3a1 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -9,7 +9,7 @@ use ra_syntax::{ }; use crate::db::AstDatabase; -use crate::{name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind}; +use crate::{guess_crate, name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind}; macro_rules! register_builtin { ( $($trait:ident => $expand:ident),* ) => { @@ -160,8 +160,7 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { let m: MacroCallId = id.into(); let file_id = m.as_file().original_file(db); let cg = db.crate_graph(); - let krates = db.relevant_crates(file_id); - let krate = match krates.get(0) { + let krate = match guess_crate(db, file_id) { Some(krate) => krate, None => { let tt = quote! { core }; @@ -172,7 +171,7 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { // XXX // All crates except core itself should have a dependency on core, // We detect `core` by seeing whether it doesn't have such a dependency. - let tt = if cg[*krate].dependencies.iter().any(|dep| dep.name == "core") { + let tt = if cg[krate].dependencies.iter().any(|dep| dep.name == "core") { quote! { core } } else { quote! { crate } diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index 7579546d2..93da3f149 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -5,7 +5,7 @@ use crate::{ name, AstId, CrateId, MacroDefId, MacroDefKind, TextSize, }; -use crate::{quote, EagerMacroId, LazyMacroId, MacroCallId}; +use crate::{guess_crate, quote, EagerMacroId, LazyMacroId, MacroCallId}; use either::Either; use mbe::parse_to_token_tree; use ra_db::FileId; @@ -335,8 +335,7 @@ fn include_expand( fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option { let call_id: MacroCallId = arg_id.into(); let original_file = call_id.as_file().original_file(db); - - let krate = *db.relevant_crates(original_file).get(0)?; + let krate = guess_crate(db, original_file)?; db.crate_graph()[krate].env.get(key) } diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index f440c073b..dc4d7f000 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -424,3 +424,8 @@ impl InFile { self.with_value(self.value.syntax()) } } + +// FIXME: this is obviously wrong, there shouldn't be any guesing here +fn guess_crate(db: &dyn db::AstDatabase, file_id: FileId) -> Option { + db.relevant_crates(file_id).iter().next().copied() +} diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs index fdf225f55..09fc18c36 100644 --- a/crates/ra_hir_expand/src/test_db.rs +++ b/crates/ra_hir_expand/src/test_db.rs @@ -6,6 +6,7 @@ use std::{ }; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate}; +use rustc_hash::FxHashSet; #[salsa::database( ra_db::SourceDatabaseExtStorage, @@ -44,7 +45,7 @@ impl FileLoader for TestDB { fn resolve_path(&self, anchor: FileId, path: &str) -> Option { FileLoaderDelegate(self).resolve_path(anchor, path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates(&self, file_id: FileId) -> Arc> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index e484968a0..ad04e3e0f 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs @@ -8,6 +8,7 @@ use std::{ use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast}; +use rustc_hash::FxHashSet; use stdx::format_to; use crate::{db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator}; @@ -73,7 +74,7 @@ impl FileLoader for TestDB { fn resolve_path(&self, anchor: FileId, path: &str) -> Option { FileLoaderDelegate(self).resolve_path(anchor, path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates(&self, file_id: FileId) -> Arc> { FileLoaderDelegate(self).relevant_crates(file_id) } } diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index 727d743b5..480fd4576 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs @@ -19,7 +19,7 @@ use ra_db::{ Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, SourceRootId, Upcast, }; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase}; @@ -60,7 +60,7 @@ impl FileLoader for RootDatabase { fn resolve_path(&self, anchor: FileId, path: &str) -> Option { FileLoaderDelegate(self).resolve_path(anchor, path) } - fn relevant_crates(&self, file_id: FileId) -> Arc> { + fn relevant_crates(&self, file_id: FileId) -> Arc> { FileLoaderDelegate(self).relevant_crates(file_id) } } -- cgit v1.2.3 From fac7b0e252ab305f5c8d69b04c46c587ee021aa9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 11 Jun 2020 12:08:24 +0200 Subject: Don't guess macro expansion crate --- crates/ra_hir/src/semantics.rs | 3 ++- crates/ra_hir/src/source_analyzer.rs | 3 ++- crates/ra_hir_def/src/body.rs | 2 +- crates/ra_hir_def/src/lib.rs | 11 ++++++--- crates/ra_hir_def/src/nameres/collector.rs | 39 +++++++++++++++++------------- crates/ra_hir_expand/src/builtin_derive.rs | 28 +++++++++------------ crates/ra_hir_expand/src/builtin_macro.rs | 17 +++++++------ crates/ra_hir_expand/src/eager.rs | 32 ++++++++++++++++++------ crates/ra_hir_expand/src/lib.rs | 16 ++++++------ 9 files changed, 89 insertions(+), 62 deletions(-) diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 7c1f79f27..a232a5856 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -122,8 +122,9 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { let macro_call = self.find_file(actual_macro_call.syntax().clone()).with_value(actual_macro_call); let sa = self.analyze2(macro_call.map(|it| it.syntax()), None); + let krate = sa.resolver.krate()?; let macro_call_id = macro_call - .as_call_id(self.db, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; + .as_call_id(self.db, krate, |path| sa.resolver.resolve_path_as_macro(self.db, &path))?; hir_expand::db::expand_hypothetical(self.db, macro_call_id, hypothetical_args, token_to_map) } diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 4b509f07c..7c6bbea13 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs @@ -307,7 +307,8 @@ impl SourceAnalyzer { db: &dyn HirDatabase, macro_call: InFile<&ast::MacroCall>, ) -> Option { - let macro_call_id = macro_call.as_call_id(db.upcast(), |path| { + let krate = self.resolver.krate()?; + let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| { self.resolver.resolve_path_as_macro(db.upcast(), &path) })?; Some(macro_call_id.as_file()) diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 273036cee..4f2350915 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -97,7 +97,7 @@ impl Expander { let macro_call = InFile::new(self.current_file_id, ¯o_call); - if let Some(call_id) = macro_call.as_call_id(db, |path| { + if let Some(call_id) = macro_call.as_call_id(db, self.crate_def_map.krate, |path| { if let Some(local_scope) = local_scope { if let Some(def) = path.as_ident().and_then(|n| local_scope.get_legacy_macro(n)) { return Some(def); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index de490fcc5..edc59e5a8 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -417,6 +417,7 @@ pub trait AsMacroCall { fn as_call_id( &self, db: &dyn db::DefDatabase, + krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, ) -> Option; } @@ -425,13 +426,14 @@ impl AsMacroCall for InFile<&ast::MacroCall> { fn as_call_id( &self, db: &dyn db::DefDatabase, + krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, ) -> Option { let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value)); let h = Hygiene::new(db.upcast(), self.file_id); let path = path::ModPath::from_src(self.value.path()?, &h)?; - AstIdWithPath::new(ast_id.file_id, ast_id.value, path).as_call_id(db, resolver) + AstIdWithPath::new(ast_id.file_id, ast_id.value, path).as_call_id(db, krate, resolver) } } @@ -452,6 +454,7 @@ impl AsMacroCall for AstIdWithPath { fn as_call_id( &self, db: &dyn db::DefDatabase, + krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, ) -> Option { let def: MacroDefId = resolver(self.path.clone())?; @@ -461,13 +464,13 @@ impl AsMacroCall for AstIdWithPath { let hygiene = Hygiene::new(db.upcast(), self.ast_id.file_id); Some( - expand_eager_macro(db.upcast(), macro_call, def, &|path: ast::Path| { + expand_eager_macro(db.upcast(), krate, macro_call, def, &|path: ast::Path| { resolver(path::ModPath::from_src(path, &hygiene)?) })? .into(), ) } else { - Some(def.as_lazy_macro(db.upcast(), MacroCallKind::FnLike(self.ast_id)).into()) + Some(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(self.ast_id)).into()) } } } @@ -476,12 +479,14 @@ impl AsMacroCall for AstIdWithPath { fn as_call_id( &self, db: &dyn db::DefDatabase, + krate: CrateId, resolver: impl Fn(path::ModPath) -> Option, ) -> Option { let def = resolver(self.path.clone())?; Some( def.as_lazy_macro( db.upcast(), + krate, MacroCallKind::Attr(self.ast_id, self.path.segments.last()?.to_string()), ) .into(), diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 353a31ad4..976e5e585 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -571,16 +571,18 @@ impl DefCollector<'_> { return false; } - if let Some(call_id) = directive.ast_id.as_call_id(self.db, |path| { - let resolved_res = self.def_map.resolve_path_fp_with_macro( - self.db, - ResolveMode::Other, - directive.module_id, - &path, - BuiltinShadowMode::Module, - ); - resolved_res.resolved_def.take_macros() - }) { + if let Some(call_id) = + directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { + let resolved_res = self.def_map.resolve_path_fp_with_macro( + self.db, + ResolveMode::Other, + directive.module_id, + &path, + BuiltinShadowMode::Module, + ); + resolved_res.resolved_def.take_macros() + }) + { resolved.push((directive.module_id, call_id, directive.depth)); res = ReachedFixedPoint::No; return false; @@ -589,9 +591,10 @@ impl DefCollector<'_> { true }); attribute_macros.retain(|directive| { - if let Some(call_id) = directive - .ast_id - .as_call_id(self.db, |path| self.resolve_attribute_macro(&directive, &path)) + if let Some(call_id) = + directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { + self.resolve_attribute_macro(&directive, &path) + }) { resolved.push((directive.module_id, call_id, 0)); res = ReachedFixedPoint::No; @@ -957,11 +960,13 @@ impl ModCollector<'_, '_> { } // Case 2: try to resolve in legacy scope and expand macro_rules - if let Some(macro_call_id) = ast_id.as_call_id(self.def_collector.db, |path| { - path.as_ident().and_then(|name| { - self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) + if let Some(macro_call_id) = + ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { + path.as_ident().and_then(|name| { + self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) + }) }) - }) { + { self.def_collector.unexpanded_macros.push(MacroDirective { module_id: self.module_id, ast_id, diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index 967d1f3a1..26b667b55 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs @@ -8,8 +8,7 @@ use ra_syntax::{ match_ast, }; -use crate::db::AstDatabase; -use crate::{guess_crate, name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind}; +use crate::{db::AstDatabase, name, quote, LazyMacroId, MacroDefId, MacroDefKind}; macro_rules! register_builtin { ( $($trait:ident => $expand:ident),* ) => { @@ -156,17 +155,8 @@ fn expand_simple_derive( fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { // FIXME: make hygiene works for builtin derive macro // such that $crate can be used here. - - let m: MacroCallId = id.into(); - let file_id = m.as_file().original_file(db); let cg = db.crate_graph(); - let krate = match guess_crate(db, file_id) { - Some(krate) => krate, - None => { - let tt = quote! { core }; - return tt.token_trees[0].clone(); - } - }; + let krate = db.lookup_intern_macro(id).krate; // XXX // All crates except core itself should have a dependency on core, @@ -263,10 +253,12 @@ fn partial_ord_expand( #[cfg(test)] mod tests { - use super::*; - use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; use name::{known, Name}; - use ra_db::{fixture::WithFixture, SourceDatabase}; + use ra_db::{fixture::WithFixture, CrateId, SourceDatabase}; + + use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; + + use super::*; fn expand_builtin_derive(s: &str, name: Name) -> String { let def = find_builtin_derive(&name).unwrap(); @@ -290,7 +282,11 @@ mod tests { let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); - let loc = MacroCallLoc { def, kind: MacroCallKind::Attr(attr_id, name.to_string()) }; + let loc = MacroCallLoc { + def, + krate: CrateId(0), + kind: MacroCallKind::Attr(attr_id, name.to_string()), + }; let id: MacroCallId = db.intern_macro(loc).into(); let parsed = db.parse_or_expand(id.as_file()).unwrap(); diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index 93da3f149..b50eb347c 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -1,15 +1,14 @@ //! Builtin macro -use crate::db::AstDatabase; use crate::{ - ast::{self, AstToken, HasStringValue}, - name, AstId, CrateId, MacroDefId, MacroDefKind, TextSize, + db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId, + MacroDefId, MacroDefKind, TextSize, }; -use crate::{guess_crate, quote, EagerMacroId, LazyMacroId, MacroCallId}; use either::Either; use mbe::parse_to_token_tree; use ra_db::FileId; use ra_parser::FragmentKind; +use ra_syntax::ast::{self, AstToken, HasStringValue}; macro_rules! register_builtin { ( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => { @@ -333,9 +332,7 @@ fn include_expand( } fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option { - let call_id: MacroCallId = arg_id.into(); - let original_file = call_id.as_file().original_file(db); - let krate = guess_crate(db, original_file)?; + let krate = db.lookup_intern_eager_expansion(arg_id).krate; db.crate_graph()[krate].env.get(key) } @@ -394,6 +391,7 @@ mod tests { let expander = find_by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); + let krate = CrateId(0); let file_id = match expander { Either::Left(expander) => { // the first one should be a macro_rules @@ -406,6 +404,7 @@ mod tests { let loc = MacroCallLoc { def, + krate, kind: MacroCallKind::FnLike(AstId::new( file_id.into(), ast_id_map.ast_id(¯o_calls[1]), @@ -418,7 +417,7 @@ mod tests { Either::Right(expander) => { // the first one should be a macro_rules let def = MacroDefId { - krate: Some(CrateId(0)), + krate: Some(krate), ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), kind: MacroDefKind::BuiltInEager(expander), local_inner: false, @@ -432,6 +431,7 @@ mod tests { def, fragment: FragmentKind::Expr, subtree: Arc::new(parsed_args.clone()), + krate, file_id: file_id.into(), } }); @@ -441,6 +441,7 @@ mod tests { def, fragment, subtree: Arc::new(subtree), + krate, file_id: file_id.into(), }; diff --git a/crates/ra_hir_expand/src/eager.rs b/crates/ra_hir_expand/src/eager.rs index 932f47c30..302d2b3e0 100644 --- a/crates/ra_hir_expand/src/eager.rs +++ b/crates/ra_hir_expand/src/eager.rs @@ -25,12 +25,14 @@ use crate::{ EagerCallLoc, EagerMacroId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; +use ra_db::CrateId; use ra_parser::FragmentKind; use ra_syntax::{algo::SyntaxRewriter, SyntaxNode}; use std::sync::Arc; pub fn expand_eager_macro( db: &dyn AstDatabase, + krate: CrateId, macro_call: InFile, def: MacroDefId, resolver: &dyn Fn(ast::Path) -> Option, @@ -47,6 +49,7 @@ pub fn expand_eager_macro( def, fragment: FragmentKind::Expr, subtree: Arc::new(parsed_args.clone()), + krate, file_id: macro_call.file_id, } }); @@ -56,14 +59,20 @@ pub fn expand_eager_macro( let result = eager_macro_recur( db, InFile::new(arg_file_id.as_file(), parsed_args.syntax_node()), + krate, resolver, )?; let subtree = to_subtree(&result)?; if let MacroDefKind::BuiltInEager(eager) = def.kind { let (subtree, fragment) = eager.expand(db, arg_id, &subtree).ok()?; - let eager = - EagerCallLoc { def, fragment, subtree: Arc::new(subtree), file_id: macro_call.file_id }; + let eager = EagerCallLoc { + def, + fragment, + subtree: Arc::new(subtree), + krate, + file_id: macro_call.file_id, + }; Some(db.intern_eager_expansion(eager)) } else { @@ -81,11 +90,12 @@ fn lazy_expand( db: &dyn AstDatabase, def: &MacroDefId, macro_call: InFile, + krate: CrateId, ) -> Option> { let ast_id = db.ast_id_map(macro_call.file_id).ast_id(¯o_call.value); let id: MacroCallId = - def.as_lazy_macro(db, MacroCallKind::FnLike(macro_call.with_value(ast_id))).into(); + def.as_lazy_macro(db, krate, MacroCallKind::FnLike(macro_call.with_value(ast_id))).into(); db.parse_or_expand(id.as_file()).map(|node| InFile::new(id.as_file(), node)) } @@ -93,6 +103,7 @@ fn lazy_expand( fn eager_macro_recur( db: &dyn AstDatabase, curr: InFile, + krate: CrateId, macro_resolver: &dyn Fn(ast::Path) -> Option, ) -> Option { let original = curr.value.clone(); @@ -105,18 +116,23 @@ fn eager_macro_recur( let def: MacroDefId = macro_resolver(child.path()?)?; let insert = match def.kind { MacroDefKind::BuiltInEager(_) => { - let id: MacroCallId = - expand_eager_macro(db, curr.with_value(child.clone()), def, macro_resolver)? - .into(); + let id: MacroCallId = expand_eager_macro( + db, + krate, + curr.with_value(child.clone()), + def, + macro_resolver, + )? + .into(); db.parse_or_expand(id.as_file())? } MacroDefKind::Declarative | MacroDefKind::BuiltIn(_) | MacroDefKind::BuiltInDerive(_) | MacroDefKind::CustomDerive(_) => { - let expanded = lazy_expand(db, &def, curr.with_value(child.clone()))?; + let expanded = lazy_expand(db, &def, curr.with_value(child.clone()), krate)?; // replace macro inside - eager_macro_recur(db, expanded, macro_resolver)? + eager_macro_recur(db, expanded, krate, macro_resolver)? } }; diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index dc4d7f000..5eac2605b 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -209,8 +209,13 @@ pub struct MacroDefId { } impl MacroDefId { - pub fn as_lazy_macro(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> LazyMacroId { - db.intern_macro(MacroCallLoc { def: self, kind }) + pub fn as_lazy_macro( + self, + db: &dyn db::AstDatabase, + krate: CrateId, + kind: MacroCallKind, + ) -> LazyMacroId { + db.intern_macro(MacroCallLoc { def: self, krate, kind }) } } @@ -227,6 +232,7 @@ pub enum MacroDefKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MacroCallLoc { pub(crate) def: MacroDefId, + pub(crate) krate: CrateId, pub(crate) kind: MacroCallKind, } @@ -274,6 +280,7 @@ pub struct EagerCallLoc { pub(crate) def: MacroDefId, pub(crate) fragment: FragmentKind, pub(crate) subtree: Arc, + pub(crate) krate: CrateId, pub(crate) file_id: HirFileId, } @@ -424,8 +431,3 @@ impl InFile { self.with_value(self.value.syntax()) } } - -// FIXME: this is obviously wrong, there shouldn't be any guesing here -fn guess_crate(db: &dyn db::AstDatabase, file_id: FileId) -> Option { - db.relevant_crates(file_id).iter().next().copied() -} -- cgit v1.2.3