Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir_def/src/db.rs2
-rw-r--r--crates/project_model/src/tests.rs2
-rw-r--r--crates/project_model/src/workspace.rs23
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs3
-rw-r--r--crates/rust-analyzer/src/config.rs4
-rw-r--r--crates/rust-analyzer/src/reload.rs51
6 files changed, 68 insertions, 17 deletions
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 7946558311..9f93bbd27b 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -55,6 +55,8 @@ pub trait InternDatabase: SourceDatabase {
pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
#[salsa::input]
fn enable_proc_attr_macros(&self) -> bool;
+ #[salsa::input]
+ fn enablse_proc_attr_macros(&self) -> bool;
#[salsa::invoke(ItemTree::file_item_tree_query)]
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs
index edf2673661..2977ff74e2 100644
--- a/crates/project_model/src/tests.rs
+++ b/crates/project_model/src/tests.rs
@@ -88,7 +88,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
}
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
- project_workspace.to_crate_graph(&mut |_| Vec::new(), &mut {
+ project_workspace.to_crate_graph(&Default::default(), &mut |_, _| Vec::new(), &mut {
let mut counter = 0;
move |_path| {
counter += 1;
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 60f99f368b..869b064e1d 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -387,10 +387,14 @@ impl ProjectWorkspace {
pub fn to_crate_graph(
&self,
- load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+ dummy_replace: &FxHashMap<Box<str>, Box<[Box<str>]>>,
+ load_proc_macro: &mut dyn FnMut(&AbsPath, &[Box<str>]) -> Vec<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
) -> CrateGraph {
let _p = profile::span("ProjectWorkspace::to_crate_graph");
+ let load_proc_macro = &mut |crate_name: &_, path: &_| {
+ load_proc_macro(path, dummy_replace.get(crate_name).map(|it| &**it).unwrap_or_default())
+ };
let mut crate_graph = match self {
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
@@ -432,7 +436,7 @@ impl ProjectWorkspace {
fn project_json_to_crate_graph(
rustc_cfg: Vec<CfgFlag>,
- load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+ load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
project: &ProjectJson,
sysroot: &Option<Sysroot>,
@@ -452,7 +456,12 @@ fn project_json_to_crate_graph(
})
.map(|(crate_id, krate, file_id)| {
let env = krate.env.clone().into_iter().collect();
- let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| load_proc_macro(&it));
+ let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| {
+ load_proc_macro(
+ krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
+ &it,
+ )
+ });
let target_cfgs = match krate.target.as_deref() {
Some(target) => {
@@ -513,7 +522,7 @@ fn project_json_to_crate_graph(
fn cargo_to_crate_graph(
rustc_cfg: Vec<CfgFlag>,
override_cfg: &CfgOverrides,
- load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+ load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
cargo: &CargoWorkspace,
build_scripts: &WorkspaceBuildScripts,
@@ -571,7 +580,7 @@ fn cargo_to_crate_graph(
&cargo[pkg],
build_scripts.outputs.get(pkg),
cfg_options,
- load_proc_macro,
+ &mut |path| load_proc_macro(&cargo[tgt].name, path),
file_id,
&cargo[tgt].name,
);
@@ -702,7 +711,7 @@ fn handle_rustc_crates(
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
crate_graph: &mut CrateGraph,
cfg_options: &CfgOptions,
- load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
+ load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> Vec<ProcMacro>,
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
public_deps: &SysrootPublicDeps,
cargo: &CargoWorkspace,
@@ -738,7 +747,7 @@ fn handle_rustc_crates(
&rustc_workspace[pkg],
None,
cfg_options,
- load_proc_macro,
+ &mut |path| load_proc_macro(&rustc_workspace[tgt].name, path),
file_id,
&rustc_workspace[tgt].name,
);
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index d60861a627..19ce86e3ff 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -66,7 +66,8 @@ pub fn load_workspace(
};
let crate_graph = ws.to_crate_graph(
- &mut |path: &AbsPath| load_proc_macro(proc_macro_client.as_ref(), path),
+ &Default::default(),
+ &mut |path: &AbsPath, _| load_proc_macro(proc_macro_client.as_ref(), path, &[]),
&mut |path: &AbsPath| {
let contents = loader.load_sync(path);
let path = vfs::VfsPath::from(path.to_path_buf());
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 818aab3515..665609cf9a 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -301,6 +301,7 @@ config_data! {
/// Internal config, path to proc-macro server executable (typically,
/// this is rust-analyzer itself, but we override this in tests).
procMacro_server: Option<PathBuf> = "null",
+ procMacro_dummies: FxHashMap<Box<str>, Box<[Box<str>]>> = "{}",
/// Command to be executed instead of 'cargo' for runnables.
runnables_overrideCargo: Option<String> = "null",
@@ -716,6 +717,9 @@ impl Config {
};
Some((path, vec!["proc-macro".into()]))
}
+ pub fn dummy_replacements(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
+ &self.data.procMacro_dummies
+ }
pub fn expand_proc_attr_macros(&self) -> bool {
self.data.experimental_procAttrMacros
}
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index b14b3dbcfa..c687466bd2 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -10,6 +10,7 @@ use ide_db::base_db::{
};
use proc_macro_api::{MacroDylib, ProcMacroServer};
use project_model::{ProjectWorkspace, WorkspaceBuildScripts};
+use syntax::SmolStr;
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
use crate::{
@@ -290,6 +291,9 @@ impl GlobalState {
}
},
};
+ self.analysis_host
+ .raw_database_mut()
+ .set_enable_proc_attr_macros(self.config.expand_proc_attr_macros());
}
let watch = match files_config.watcher {
@@ -306,8 +310,9 @@ impl GlobalState {
// Create crate graph from all the workspaces
let crate_graph = {
let proc_macro_client = self.proc_macro_client.as_ref();
- let mut load_proc_macro =
- move |path: &AbsPath| load_proc_macro(proc_macro_client, path);
+ let mut load_proc_macro = move |path: &AbsPath, dummy_replace: &_| {
+ load_proc_macro(proc_macro_client, path, dummy_replace)
+ };
let vfs = &mut self.vfs.write().0;
let loader = &mut self.loader;
@@ -328,7 +333,11 @@ impl GlobalState {
let mut crate_graph = CrateGraph::default();
for ws in self.workspaces.iter() {
- crate_graph.extend(ws.to_crate_graph(&mut load_proc_macro, &mut load));
+ crate_graph.extend(ws.to_crate_graph(
+ self.config.dummy_replacements(),
+ &mut load_proc_macro,
+ &mut load,
+ ));
}
crate_graph
};
@@ -505,7 +514,11 @@ impl SourceRootConfig {
}
}
-pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath) -> Vec<ProcMacro> {
+pub(crate) fn load_proc_macro(
+ client: Option<&ProcMacroServer>,
+ path: &AbsPath,
+ dummy_replace: &[Box<str>],
+) -> Vec<ProcMacro> {
let dylib = match MacroDylib::new(path.to_path_buf()) {
Ok(it) => it,
Err(err) => {
@@ -532,17 +545,25 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath)
Vec::new()
}
})
- .map(expander_to_proc_macro)
+ .map(|expander| expander_to_proc_macro(expander, dummy_replace))
.collect();
- fn expander_to_proc_macro(expander: proc_macro_api::ProcMacro) -> ProcMacro {
- let name = expander.name().into();
+ fn expander_to_proc_macro(
+ expander: proc_macro_api::ProcMacro,
+ dummy_replace: &[Box<str>],
+ ) -> ProcMacro {
+ let name = SmolStr::from(expander.name());
let kind = match expander.kind() {
proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive,
proc_macro_api::ProcMacroKind::FuncLike => ProcMacroKind::FuncLike,
proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr,
};
- let expander = Arc::new(Expander(expander));
+ let expander: Arc<dyn ProcMacroExpander> =
+ if dummy_replace.iter().any(|replace| &**replace == name) {
+ Arc::new(DummyExpander)
+ } else {
+ Arc::new(Expander(expander))
+ };
ProcMacro { name, kind, expander }
}
@@ -564,6 +585,20 @@ pub(crate) fn load_proc_macro(client: Option<&ProcMacroServer>, path: &AbsPath)
}
}
}
+
+ #[derive(Debug)]
+ struct DummyExpander;
+
+ impl ProcMacroExpander for DummyExpander {
+ fn expand(
+ &self,
+ subtree: &tt::Subtree,
+ _: Option<&tt::Subtree>,
+ _: &Env,
+ ) -> Result<tt::Subtree, ProcMacroExpansionError> {
+ Ok(subtree.clone())
+ }
+ }
}
pub(crate) fn should_refresh_for_change(path: &AbsPath, change_kind: ChangeKind) -> bool {