diff --git a/Cargo.lock b/Cargo.lock index 10ea555505..3bb1df05b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -928,6 +928,7 @@ dependencies = [ "ra_cfg", "ra_prof", "ra_syntax", + "ra_tt", "relative-path", "rustc-hash", "salsa", @@ -1081,6 +1082,13 @@ dependencies = [ "drop_bomb", ] +[[package]] +name = "ra_proc_macro" +version = "0.1.0" +dependencies = [ + "ra_tt", +] + [[package]] name = "ra_prof" version = "0.1.0" @@ -1102,6 +1110,7 @@ dependencies = [ "ra_cargo_watch", "ra_cfg", "ra_db", + "ra_proc_macro", "rustc-hash", "serde", "serde_json", diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml index 878c22ba98..8ab409158c 100644 --- a/crates/ra_db/Cargo.toml +++ b/crates/ra_db/Cargo.toml @@ -15,4 +15,5 @@ rustc-hash = "1.1.0" ra_syntax = { path = "../ra_syntax" } ra_cfg = { path = "../ra_cfg" } ra_prof = { path = "../ra_prof" } +ra_tt = { path = "../ra_tt" } test_utils = { path = "../test_utils" } diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs index 5e3e9203cd..7777ce81e7 100644 --- a/crates/ra_db/src/fixture.rs +++ b/crates/ra_db/src/fixture.rs @@ -70,6 +70,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId meta.cfg, meta.env, Default::default(), + Default::default(), ); crate_graph } else { @@ -81,6 +82,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); crate_graph }; @@ -130,6 +132,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option Option, +} + +impl Eq for ProcMacro {} +impl PartialEq for ProcMacro { + fn eq(&self, other: &ProcMacro) -> bool { + self.name == other.name && Arc::ptr_eq(&self.expander, &other.expander) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct CrateData { pub root_file_id: FileId, @@ -127,6 +145,7 @@ pub struct CrateData { pub env: Env, pub extern_source: ExternSource, pub dependencies: Vec, + pub proc_macro: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -166,7 +185,11 @@ impl CrateGraph { cfg_options: CfgOptions, env: Env, extern_source: ExternSource, + proc_macro: Vec<(SmolStr, Arc)>, ) -> CrateId { + let proc_macro = + proc_macro.into_iter().map(|(name, it)| ProcMacro { name, expander: it }).collect(); + let data = CrateData { root_file_id: file_id, edition, @@ -174,6 +197,7 @@ impl CrateGraph { cfg_options, env, extern_source, + proc_macro, dependencies: Vec::new(), }; let crate_id = CrateId(self.arena.len() as u32); @@ -345,6 +369,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let crate2 = graph.add_crate_root( FileId(2u32), @@ -353,6 +378,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let crate3 = graph.add_crate_root( FileId(3u32), @@ -361,6 +387,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); @@ -377,6 +404,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let crate2 = graph.add_crate_root( FileId(2u32), @@ -385,6 +413,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let crate3 = graph.add_crate_root( FileId(3u32), @@ -393,6 +422,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok()); assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok()); @@ -408,6 +438,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let crate2 = graph.add_crate_root( FileId(2u32), @@ -416,6 +447,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); assert!(graph .add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2) diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index bac24e2186..a06f59c140 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -12,7 +12,7 @@ pub use crate::{ cancellation::Canceled, input::{ CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId, - FileId, SourceRoot, SourceRootId, + FileId, ProcMacroId, SourceRoot, SourceRootId, }, }; pub use relative_path::{RelativePath, RelativePathBuf}; diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 9c125f32f3..8fe3f8617f 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -11,7 +11,7 @@ use hir_expand::{ HirFileId, MacroCallId, MacroDefId, MacroDefKind, }; use ra_cfg::CfgOptions; -use ra_db::{CrateId, FileId}; +use ra_db::{CrateId, FileId, ProcMacroId}; use ra_syntax::ast; use rustc_hash::FxHashMap; use test_utils::tested_by; @@ -53,6 +53,16 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr } let cfg_options = &crate_graph[def_map.krate].cfg_options; + let proc_macros = &crate_graph[def_map.krate].proc_macro; + let proc_macros = proc_macros + .iter() + .enumerate() + .map(|(idx, it)| { + // FIXME: a hacky way to create a Name from string. + let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() }; + (name.as_name(), ProcMacroExpander::new(def_map.krate, ProcMacroId(idx as u32))) + }) + .collect(); let mut collector = DefCollector { db, @@ -65,9 +75,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), cfg_options, - - // FIXME: pass proc-macro from crate-graph - proc_macros: Default::default(), + proc_macros, }; collector.collect(); collector.finish() diff --git a/crates/ra_hir_expand/src/proc_macro.rs b/crates/ra_hir_expand/src/proc_macro.rs index a8dee20526..4d270e0def 100644 --- a/crates/ra_hir_expand/src/proc_macro.rs +++ b/crates/ra_hir_expand/src/proc_macro.rs @@ -1,33 +1,32 @@ //! Proc Macro Expander stub -use crate::{db::AstDatabase, LazyMacroId, MacroCallKind, MacroCallLoc}; -use ra_db::CrateId; +use crate::{db::AstDatabase, LazyMacroId}; +use ra_db::{CrateId, ProcMacroId}; #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct ProcMacroExpander { krate: CrateId, + proc_macro_id: ProcMacroId, } impl ProcMacroExpander { - pub fn new(krate: CrateId) -> ProcMacroExpander { - ProcMacroExpander { krate } + pub fn new(krate: CrateId, proc_macro_id: ProcMacroId) -> ProcMacroExpander { + ProcMacroExpander { krate, proc_macro_id } } pub fn expand( &self, db: &dyn AstDatabase, - id: LazyMacroId, - _tt: &tt::Subtree, + _id: LazyMacroId, + tt: &tt::Subtree, ) -> Result { - let loc: MacroCallLoc = db.lookup_intern_macro(id); - let name = match loc.kind { - MacroCallKind::FnLike(_) => return Err(mbe::ExpandError::ConversionError), - MacroCallKind::Attr(_, name) => name, - }; + let krate_graph = db.crate_graph(); + let proc_macro = krate_graph[self.krate] + .proc_macro + .get(self.proc_macro_id.0 as usize) + .clone() + .ok_or_else(|| mbe::ExpandError::ConversionError)?; - log::debug!("Proc-macro-expanding name = {}", name); - - // Return nothing for now - return Ok(tt::Subtree::default()); + proc_macro.expander.expand(&tt, None).map_err(mbe::ExpandError::from) } } diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 5ab06c6cfd..e43414985f 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -213,6 +213,7 @@ impl Analysis { cfg_options, Env::default(), Default::default(), + Default::default(), ); change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text)); change.set_crate_graph(crate_graph); diff --git a/crates/ra_ide/src/mock_analysis.rs b/crates/ra_ide/src/mock_analysis.rs index 2cf77a31f5..2c13f206a1 100644 --- a/crates/ra_ide/src/mock_analysis.rs +++ b/crates/ra_ide/src/mock_analysis.rs @@ -103,6 +103,7 @@ impl MockAnalysis { cfg_options, Env::default(), Default::default(), + Default::default(), )); } else if path.ends_with("/lib.rs") { let crate_name = path.parent().unwrap().file_name().unwrap(); @@ -113,6 +114,7 @@ impl MockAnalysis { cfg_options, Env::default(), Default::default(), + Default::default(), ); if let Some(root_crate) = root_crate { crate_graph diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index 76d130b9b9..958b92bed5 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs @@ -137,6 +137,7 @@ mod tests { CfgOptions::default(), Env::default(), Default::default(), + Default::default(), ); let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 6a9037bfc8..535b7daa07 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -28,6 +28,13 @@ pub enum ExpandError { BindingError(String), ConversionError, InvalidRepeat, + ProcMacroError(tt::ExpansionError), +} + +impl From for ExpandError { + fn from(it: tt::ExpansionError) -> Self { + ExpandError::ProcMacroError(it) + } } pub use crate::syntax_bridge::{ diff --git a/crates/ra_proc_macro/Cargo.toml b/crates/ra_proc_macro/Cargo.toml new file mode 100644 index 0000000000..bc2c37296d --- /dev/null +++ b/crates/ra_proc_macro/Cargo.toml @@ -0,0 +1,12 @@ +[package] +edition = "2018" +name = "ra_proc_macro" +version = "0.1.0" +authors = ["rust-analyzer developers"] +publish = false + +[lib] +doctest = false + +[dependencies] +ra_tt = { path = "../ra_tt" } diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs new file mode 100644 index 0000000000..5e21dd4872 --- /dev/null +++ b/crates/ra_proc_macro/src/lib.rs @@ -0,0 +1,59 @@ +//! Client-side Proc-Macro crate +//! +//! We separate proc-macro expanding logic to an extern program to allow +//! different implementations (e.g. wasm or dylib loading). And this crate +//! is used to provide basic infrastructure for communication between two +//! processes: Client (RA itself), Server (the external program) + +use ra_tt::{SmolStr, Subtree}; +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ProcMacroProcessExpander { + process: Arc, + name: SmolStr, +} + +impl ra_tt::TokenExpander for ProcMacroProcessExpander { + fn expand( + &self, + _subtree: &Subtree, + _attr: Option<&Subtree>, + ) -> Result { + // FIXME: do nothing for now + Ok(Subtree::default()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ProcMacroProcessSrv { + path: PathBuf, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ProcMacroClient { + Process { process: Arc }, + Dummy, +} + +impl ProcMacroClient { + pub fn extern_process(process_path: &Path) -> ProcMacroClient { + let process = ProcMacroProcessSrv { path: process_path.into() }; + ProcMacroClient::Process { process: Arc::new(process) } + } + + pub fn dummy() -> ProcMacroClient { + ProcMacroClient::Dummy + } + + pub fn by_dylib_path( + &self, + _dylib_path: &Path, + ) -> Vec<(SmolStr, Arc)> { + // FIXME: return empty for now + vec![] + } +} diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml index 22300548a7..cdcdd63c91 100644 --- a/crates/ra_project_model/Cargo.toml +++ b/crates/ra_project_model/Cargo.toml @@ -17,6 +17,7 @@ ra_arena = { path = "../ra_arena" } ra_db = { path = "../ra_db" } ra_cfg = { path = "../ra_cfg" } ra_cargo_watch = { path = "../ra_cargo_watch" } +ra_proc_macro = { path = "../ra_proc_macro" } serde = { version = "1.0.104", features = ["derive"] } serde_json = "1.0.48" diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index c7f9bd873e..291594e2a2 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -83,6 +83,7 @@ pub struct PackageData { pub edition: Edition, pub features: Vec, pub out_dir: Option, + pub proc_macro_dylib_path: Option, } #[derive(Debug, Clone)] @@ -158,8 +159,11 @@ impl CargoWorkspace { })?; let mut out_dir_by_id = FxHashMap::default(); + let mut proc_macro_dylib_paths = FxHashMap::default(); if cargo_features.load_out_dirs_from_check { - out_dir_by_id = load_out_dirs(cargo_toml, cargo_features); + let resources = load_extern_resources(cargo_toml, cargo_features); + out_dir_by_id = resources.out_dirs; + proc_macro_dylib_paths = resources.proc_dylib_paths; } let mut pkg_by_id = FxHashMap::default(); @@ -183,6 +187,7 @@ impl CargoWorkspace { dependencies: Vec::new(), features: Vec::new(), out_dir: out_dir_by_id.get(&id).cloned(), + proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), }); let pkg_data = &mut packages[pkg]; pkg_by_id.insert(id, pkg); @@ -246,10 +251,13 @@ impl CargoWorkspace { } } -pub fn load_out_dirs( - cargo_toml: &Path, - cargo_features: &CargoFeatures, -) -> FxHashMap { +#[derive(Debug, Clone, Default)] +pub struct ExternResources { + out_dirs: FxHashMap, + proc_dylib_paths: FxHashMap, +} + +pub fn load_extern_resources(cargo_toml: &Path, cargo_features: &CargoFeatures) -> ExternResources { let mut args: Vec = vec![ "check".to_string(), "--message-format=json".to_string(), @@ -267,14 +275,21 @@ pub fn load_out_dirs( args.extend(cargo_features.features.iter().cloned()); } - let mut acc = FxHashMap::default(); + let mut acc = ExternResources::default(); let res = run_cargo(&args, cargo_toml.parent(), &mut |message| { match message { Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { - acc.insert(package_id, out_dir); + acc.out_dirs.insert(package_id, out_dir); } - Message::CompilerArtifact(_) => (), + Message::CompilerArtifact(message) => { + if message.target.kind.contains(&"proc-macro".to_string()) { + let package_id = message.package_id; + if let Some(filename) = message.filenames.get(0) { + acc.proc_dylib_paths.insert(package_id, filename.clone()); + } + } + } Message::CompilerMessage(_) => (), Message::Unknown => (), } diff --git a/crates/ra_project_model/src/json_project.rs b/crates/ra_project_model/src/json_project.rs index 336446e58c..b030c8a6a1 100644 --- a/crates/ra_project_model/src/json_project.rs +++ b/crates/ra_project_model/src/json_project.rs @@ -23,6 +23,7 @@ pub struct Crate { pub(crate) atom_cfgs: FxHashSet, pub(crate) key_value_cfgs: FxHashMap, pub(crate) out_dir: Option, + pub(crate) proc_macro_dylib_path: Option, } #[derive(Clone, Copy, Debug, Deserialize)] diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index a3ef9acdc6..444d3bb3f0 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -23,6 +23,7 @@ pub use crate::{ json_project::JsonProject, sysroot::Sysroot, }; +pub use ra_proc_macro::ProcMacroClient; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct CargoTomlNotFoundError { @@ -173,6 +174,29 @@ impl ProjectWorkspace { } } + pub fn proc_macro_dylib_paths(&self) -> Vec { + match self { + ProjectWorkspace::Json { project } => { + let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len()); + for krate in &project.crates { + if let Some(out_dir) = &krate.proc_macro_dylib_path { + proc_macro_dylib_paths.push(out_dir.to_path_buf()); + } + } + proc_macro_dylib_paths + } + ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { + let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len()); + for pkg in cargo.packages() { + if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path { + proc_macro_dylib_paths.push(dylib_path.to_path_buf()); + } + } + proc_macro_dylib_paths + } + } + } + pub fn n_packages(&self) -> usize { match self { ProjectWorkspace::Json { project } => project.crates.len(), @@ -186,6 +210,7 @@ impl ProjectWorkspace { &self, default_cfg_options: &CfgOptions, extern_source_roots: &FxHashMap, + proc_macro_client: &ProcMacroClient, load: &mut dyn FnMut(&Path) -> Option, ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); @@ -219,7 +244,10 @@ impl ProjectWorkspace { extern_source.set_extern_path(&out_dir, extern_source_id); } } - + let proc_macro = krate + .proc_macro_dylib_path + .clone() + .map(|it| proc_macro_client.by_dylib_path(&it)); // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env crates.insert( crate_id, @@ -231,6 +259,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro.unwrap_or_default(), ), ); } @@ -270,6 +299,8 @@ impl ProjectWorkspace { let env = Env::default(); let extern_source = ExternSource::default(); + let proc_macro = vec![]; + let crate_id = crate_graph.add_crate_root( file_id, Edition::Edition2018, @@ -280,6 +311,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro, ); sysroot_crates.insert(krate, crate_id); } @@ -327,6 +359,12 @@ impl ProjectWorkspace { extern_source.set_extern_path(&out_dir, extern_source_id); } } + let proc_macro = cargo[pkg] + .proc_macro_dylib_path + .as_ref() + .map(|it| proc_macro_client.by_dylib_path(&it)) + .unwrap_or_default(); + let crate_id = crate_graph.add_crate_root( file_id, edition, @@ -334,6 +372,7 @@ impl ProjectWorkspace { cfg_options, env, extern_source, + proc_macro.clone(), ); if cargo[tgt].kind == TargetKind::Lib { lib_tgt = Some((crate_id, cargo[tgt].name.clone())); diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs index 1e2fb8b913..1015ce0a60 100644 --- a/crates/ra_tt/src/lib.rs +++ b/crates/ra_tt/src/lib.rs @@ -14,9 +14,12 @@ macro_rules! impl_froms { } } -use std::fmt; +use std::{ + fmt::{self, Debug}, + panic::RefUnwindSafe, +}; -use smol_str::SmolStr; +pub use smol_str::SmolStr; /// Represents identity of the token. /// @@ -184,3 +187,11 @@ impl Subtree { } pub mod buffer; + +#[derive(Debug, PartialEq, Eq)] +pub enum ExpansionError {} + +pub trait TokenExpander: Debug + Send + Sync + RefUnwindSafe { + fn expand(&self, subtree: &Subtree, attrs: Option<&Subtree>) + -> Result; +} diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 54e2fa1a7c..832f04226c 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -7,7 +7,9 @@ use anyhow::Result; use crossbeam_channel::{unbounded, Receiver}; use ra_db::{ExternSourceId, FileId, SourceRootId}; use ra_ide::{AnalysisChange, AnalysisHost}; -use ra_project_model::{get_rustc_cfg_options, CargoFeatures, PackageRoot, ProjectWorkspace}; +use ra_project_model::{ + get_rustc_cfg_options, CargoFeatures, PackageRoot, ProcMacroClient, ProjectWorkspace, +}; use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -67,7 +69,9 @@ pub(crate) fn load_cargo( (source_root_id, project_root) }) .collect::>(); - let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs); + + let proc_macro_client = ProcMacroClient::dummy(); + let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs, &proc_macro_client); Ok((host, source_roots)) } @@ -77,6 +81,7 @@ pub(crate) fn load( vfs: &mut Vfs, receiver: Receiver, extern_dirs: FxHashSet, + proc_macro_client: &ProcMacroClient, ) -> AnalysisHost { let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::().ok()); let mut host = AnalysisHost::new(lru_cap); @@ -143,12 +148,16 @@ pub(crate) fn load( opts }; - let crate_graph = - ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &mut |path: &Path| { + let crate_graph = ws.to_crate_graph( + &default_cfg_options, + &extern_source_roots, + proc_macro_client, + &mut |path: &Path| { let vfs_file = vfs.load(path); log::debug!("vfs file {:?} -> {:?}", path, vfs_file); vfs_file.map(vfs_file_to_id) - }); + }, + ); log::debug!("crate graph: {:?}", crate_graph); analysis_change.set_crate_graph(crate_graph); diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs index c4244fee24..de85bb0178 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/world.rs @@ -16,7 +16,7 @@ use ra_ide::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, InlayHintsOptions, LibraryData, SourceRootId, }; -use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace}; +use ra_project_model::{get_rustc_cfg_options, ProcMacroClient, ProjectWorkspace}; use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; use relative_path::RelativePathBuf; @@ -150,9 +150,19 @@ impl WorldState { vfs_file.map(|f| FileId(f.0)) }; + let proc_macro_client = + ProcMacroClient::extern_process(std::path::Path::new("ra_proc_macro_srv")); + workspaces .iter() - .map(|ws| ws.to_crate_graph(&default_cfg_options, &extern_source_roots, &mut load)) + .map(|ws| { + ws.to_crate_graph( + &default_cfg_options, + &extern_source_roots, + &proc_macro_client, + &mut load, + ) + }) .for_each(|graph| { crate_graph.extend(graph); });