Split out proc-macros from the CrateGraph

This commit is contained in:
Lukas Wirth 2023-03-25 16:42:52 +01:00
parent 71b23360e7
commit d154ea88f9
12 changed files with 141 additions and 176 deletions

View File

@ -6,7 +6,7 @@ use std::{fmt, sync::Arc};
use salsa::Durability; use salsa::Durability;
use vfs::FileId; use vfs::FileId;
use crate::{CrateGraph, SourceDatabaseExt, SourceRoot, SourceRootId}; use crate::{CrateGraph, ProcMacros, SourceDatabaseExt, SourceRoot, SourceRootId};
/// Encapsulate a bunch of raw `.set` calls on the database. /// Encapsulate a bunch of raw `.set` calls on the database.
#[derive(Default)] #[derive(Default)]
@ -14,6 +14,7 @@ pub struct Change {
pub roots: Option<Vec<SourceRoot>>, pub roots: Option<Vec<SourceRoot>>,
pub files_changed: Vec<(FileId, Option<Arc<String>>)>, pub files_changed: Vec<(FileId, Option<Arc<String>>)>,
pub crate_graph: Option<CrateGraph>, pub crate_graph: Option<CrateGraph>,
pub proc_macros: Option<ProcMacros>,
} }
impl fmt::Debug for Change { impl fmt::Debug for Change {
@ -49,6 +50,10 @@ impl Change {
self.crate_graph = Some(graph); self.crate_graph = Some(graph);
} }
pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
self.proc_macros = Some(proc_macros);
}
pub fn apply(self, db: &mut dyn SourceDatabaseExt) { pub fn apply(self, db: &mut dyn SourceDatabaseExt) {
let _p = profile::span("RootDatabase::apply_change"); let _p = profile::span("RootDatabase::apply_change");
if let Some(roots) = self.roots { if let Some(roots) = self.roots {
@ -73,6 +78,9 @@ impl Change {
if let Some(crate_graph) = self.crate_graph { if let Some(crate_graph) = self.crate_graph {
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH) db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH)
} }
if let Some(proc_macros) = self.proc_macros {
db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH)
}
} }
} }

View File

@ -12,8 +12,8 @@ use vfs::{file_set::FileSet, VfsPath};
use crate::{ use crate::{
input::{CrateName, CrateOrigin, LangCrateOrigin}, input::{CrateName, CrateOrigin, LangCrateOrigin},
Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, FileId, FilePosition, Change, CrateDisplayName, CrateGraph, CrateId, Dependency, Edition, Env, FileId, FilePosition,
FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, SourceDatabaseExt, FileRange, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacros,
SourceRoot, SourceRootId, SourceDatabaseExt, SourceRoot, SourceRootId,
}; };
pub const WORKSPACE: SourceRootId = SourceRootId(0); pub const WORKSPACE: SourceRootId = SourceRootId(0);
@ -100,7 +100,7 @@ impl ChangeFixture {
pub fn parse_with_proc_macros( pub fn parse_with_proc_macros(
ra_fixture: &str, ra_fixture: &str,
mut proc_macros: Vec<(String, ProcMacro)>, mut proc_macro_defs: Vec<(String, ProcMacro)>,
) -> ChangeFixture { ) -> ChangeFixture {
let (mini_core, proc_macro_names, fixture) = Fixture::parse(ra_fixture); let (mini_core, proc_macro_names, fixture) = Fixture::parse(ra_fixture);
let mut change = Change::new(); let mut change = Change::new();
@ -160,7 +160,6 @@ impl ChangeFixture {
meta.cfg.clone(), meta.cfg.clone(),
meta.cfg, meta.cfg,
meta.env, meta.env,
Ok(Vec::new()),
false, false,
origin, origin,
meta.target_data_layout meta.target_data_layout
@ -200,7 +199,6 @@ impl ChangeFixture {
default_cfg.clone(), default_cfg.clone(),
default_cfg, default_cfg,
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
default_target_data_layout default_target_data_layout
@ -244,7 +242,6 @@ impl ChangeFixture {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::Lang(LangCrateOrigin::Core), CrateOrigin::Lang(LangCrateOrigin::Core),
target_layout.clone(), target_layout.clone(),
@ -257,12 +254,13 @@ impl ChangeFixture {
} }
} }
let mut proc_macros = ProcMacros::default();
if !proc_macro_names.is_empty() { if !proc_macro_names.is_empty() {
let proc_lib_file = file_id; let proc_lib_file = file_id;
file_id.0 += 1; file_id.0 += 1;
proc_macros.extend(default_test_proc_macros()); proc_macro_defs.extend(default_test_proc_macros());
let (proc_macro, source) = filter_test_proc_macros(&proc_macro_names, proc_macros); let (proc_macro, source) = filter_test_proc_macros(&proc_macro_names, proc_macro_defs);
let mut fs = FileSet::default(); let mut fs = FileSet::default();
fs.insert( fs.insert(
proc_lib_file, proc_lib_file,
@ -282,11 +280,11 @@ impl ChangeFixture {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(proc_macro),
true, true,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
target_layout, target_layout,
); );
proc_macros.insert(proc_macros_crate, Ok(proc_macro));
for krate in all_crates { for krate in all_crates {
crate_graph crate_graph
@ -305,6 +303,7 @@ impl ChangeFixture {
roots.push(root); roots.push(root);
change.set_roots(roots); change.set_roots(roots);
change.set_crate_graph(crate_graph); change.set_crate_graph(crate_graph);
change.set_proc_macros(proc_macros);
ChangeFixture { file_position, files, change } ChangeFixture { file_position, files, change }
} }

View File

@ -15,6 +15,8 @@ use syntax::SmolStr;
use tt::token_id::Subtree; use tt::token_id::Subtree;
use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath}; use vfs::{file_set::FileSet, AnchoredPath, FileId, VfsPath};
pub type ProcMacros = FxHashMap<CrateId, ProcMacroLoadResult>;
/// Files are grouped into source roots. A source root is a directory on the /// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a /// file systems which is watched for changes. Typically it corresponds to a
/// Rust crate. Source roots *might* be nested: in this case, a file belongs to /// Rust crate. Source roots *might* be nested: in this case, a file belongs to
@ -269,7 +271,6 @@ pub struct CrateData {
pub target_layout: TargetLayoutLoadResult, pub target_layout: TargetLayoutLoadResult,
pub env: Env, pub env: Env,
pub dependencies: Vec<Dependency>, pub dependencies: Vec<Dependency>,
pub proc_macro: ProcMacroLoadResult,
pub origin: CrateOrigin, pub origin: CrateOrigin,
pub is_proc_macro: bool, pub is_proc_macro: bool,
} }
@ -322,7 +323,6 @@ impl CrateGraph {
cfg_options: CfgOptions, cfg_options: CfgOptions,
potential_cfg_options: CfgOptions, potential_cfg_options: CfgOptions,
env: Env, env: Env,
proc_macro: ProcMacroLoadResult,
is_proc_macro: bool, is_proc_macro: bool,
origin: CrateOrigin, origin: CrateOrigin,
target_layout: Result<Arc<str>, Arc<str>>, target_layout: Result<Arc<str>, Arc<str>>,
@ -335,7 +335,6 @@ impl CrateGraph {
cfg_options, cfg_options,
potential_cfg_options, potential_cfg_options,
env, env,
proc_macro,
dependencies: Vec::new(), dependencies: Vec::new(),
origin, origin,
target_layout, target_layout,
@ -460,7 +459,12 @@ impl CrateGraph {
/// ///
/// The ids of the crates in the `other` graph are shifted by the return /// The ids of the crates in the `other` graph are shifted by the return
/// amount. /// amount.
pub fn extend(&mut self, other: CrateGraph) -> u32 { pub fn extend(
&mut self,
other: CrateGraph,
proc_macros: &mut ProcMacros,
other_proc_macros: ProcMacros,
) -> u32 {
let start = self.arena.len() as u32; let start = self.arena.len() as u32;
self.arena.extend(other.arena.into_iter().map(|(id, mut data)| { self.arena.extend(other.arena.into_iter().map(|(id, mut data)| {
let new_id = id.shift(start); let new_id = id.shift(start);
@ -469,6 +473,8 @@ impl CrateGraph {
} }
(new_id, data) (new_id, data)
})); }));
proc_macros
.extend(other_proc_macros.into_iter().map(|(id, macros)| (id.shift(start), macros)));
start start
} }
@ -645,7 +651,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -658,7 +663,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -671,7 +675,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -698,7 +701,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -711,7 +713,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -735,7 +736,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -748,7 +748,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -761,7 +760,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -785,7 +783,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),
@ -798,7 +795,6 @@ mod tests {
CfgOptions::default(), CfgOptions::default(),
CfgOptions::default(), CfgOptions::default(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("".into()), Err("".into()),

View File

@ -16,7 +16,7 @@ pub use crate::{
input::{ input::{
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, Edition, Env, LangCrateOrigin, ProcMacro, ProcMacroExpander, ProcMacroExpansionError,
ProcMacroId, ProcMacroKind, ProcMacroLoadResult, SourceRoot, SourceRootId, ProcMacroId, ProcMacroKind, ProcMacroLoadResult, ProcMacros, SourceRoot, SourceRootId,
TargetLayoutLoadResult, TargetLayoutLoadResult,
}, },
}; };
@ -73,6 +73,10 @@ pub trait SourceDatabase: FileLoader + std::fmt::Debug {
/// The crate graph. /// The crate graph.
#[salsa::input] #[salsa::input]
fn crate_graph(&self) -> Arc<CrateGraph>; fn crate_graph(&self) -> Arc<CrateGraph>;
/// The crate graph.
#[salsa::input]
fn proc_macros(&self) -> Arc<ProcMacros>;
} }
fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> {

View File

@ -78,25 +78,35 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
} }
let cfg_options = &krate.cfg_options; let cfg_options = &krate.cfg_options;
let proc_macros = match &krate.proc_macro {
Ok(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(), span: tt::TokenId::unspecified() };
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
})
.collect()
}
Err(e) => {
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
Vec::new()
}
};
let is_proc_macro = krate.is_proc_macro; let is_proc_macro = krate.is_proc_macro;
let proc_macros = if is_proc_macro {
match db.proc_macros().get(&def_map.krate) {
Some(Ok(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(), span: tt::TokenId::unspecified() };
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
})
.collect()
}
Some(Err(e)) => {
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
Vec::new()
}
None => {
def_map.proc_macro_loading_error =
Some("No proc-macros present for crate".to_owned().into_boxed_str());
Vec::new()
}
}
} else {
vec![]
};
let mut collector = DefCollector { let mut collector = DefCollector {
db, db,

View File

@ -33,10 +33,10 @@ impl ProcMacroExpander {
) -> ExpandResult<tt::Subtree> { ) -> ExpandResult<tt::Subtree> {
match self.proc_macro_id { match self.proc_macro_id {
Some(id) => { Some(id) => {
let krate_graph = db.crate_graph(); let proc_macros = db.proc_macros();
let proc_macros = match &krate_graph[def_crate].proc_macro { let proc_macros = match proc_macros.get(&def_crate) {
Ok(proc_macros) => proc_macros, Some(Ok(proc_macros)) => proc_macros,
Err(_) => { Some(Err(_)) | None => {
never!("Non-dummy expander even though there are no proc macros"); never!("Non-dummy expander even though there are no proc macros");
return ExpandResult::with_err( return ExpandResult::with_err(
tt::Subtree::empty(), tt::Subtree::empty(),
@ -59,6 +59,7 @@ impl ProcMacroExpander {
} }
}; };
let krate_graph = db.crate_graph();
// Proc macros have access to the environment variables of the invoking crate. // Proc macros have access to the environment variables of the invoking crate.
let env = &krate_graph[calling_crate].env; let env = &krate_graph[calling_crate].env;
match proc_macro.expander.expand(tt, attr_arg, env) { match proc_macro.expander.expand(tt, attr_arg, env) {

View File

@ -235,7 +235,6 @@ impl Analysis {
cfg_options.clone(), cfg_options.clone(),
cfg_options, cfg_options,
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { repo: None, name: None }, CrateOrigin::CratesIo { repo: None, name: None },
Err("Analysis::from_single_file has no target layout".into()), Err("Analysis::from_single_file has no target layout".into()),

View File

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use ide_db::{ use ide_db::{
base_db::{salsa::Durability, CrateGraph, SourceDatabase}, base_db::{salsa::Durability, CrateGraph, ProcMacros, SourceDatabase},
FxHashMap, RootDatabase, FxHashMap, RootDatabase,
}; };
@ -16,6 +16,7 @@ use ide_db::{
// |=== // |===
pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) { pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
let crate_graph = db.crate_graph(); let crate_graph = db.crate_graph();
let proc_macros = db.proc_macros();
let mut shuffled_ids = crate_graph.iter().collect::<Vec<_>>(); let mut shuffled_ids = crate_graph.iter().collect::<Vec<_>>();
@ -23,6 +24,7 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
stdx::rand::shuffle(&mut shuffled_ids, |i| rng.rand_range(0..i as u32) as usize); stdx::rand::shuffle(&mut shuffled_ids, |i| rng.rand_range(0..i as u32) as usize);
let mut new_graph = CrateGraph::default(); let mut new_graph = CrateGraph::default();
let mut new_proc_macros = ProcMacros::default();
let mut map = FxHashMap::default(); let mut map = FxHashMap::default();
for old_id in shuffled_ids.iter().copied() { for old_id in shuffled_ids.iter().copied() {
@ -35,11 +37,11 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
data.cfg_options.clone(), data.cfg_options.clone(),
data.potential_cfg_options.clone(), data.potential_cfg_options.clone(),
data.env.clone(), data.env.clone(),
data.proc_macro.clone(),
data.is_proc_macro, data.is_proc_macro,
data.origin.clone(), data.origin.clone(),
data.target_layout.clone(), data.target_layout.clone(),
); );
new_proc_macros.insert(new_id, proc_macros[&old_id].clone());
map.insert(old_id, new_id); map.insert(old_id, new_id);
} }
@ -53,4 +55,5 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
} }
db.set_crate_graph_with_durability(Arc::new(new_graph), Durability::HIGH); db.set_crate_graph_with_durability(Arc::new(new_graph), Durability::HIGH);
db.set_proc_macros_with_durability(Arc::new(new_proc_macros), Durability::HIGH);
} }

View File

@ -3,7 +3,7 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use base_db::{CrateGraph, FileId}; use base_db::{CrateGraph, FileId, ProcMacros};
use cfg::{CfgAtom, CfgDiff}; use cfg::{CfgAtom, CfgDiff};
use expect_test::{expect, Expect}; use expect_test::{expect, Expect};
use paths::{AbsPath, AbsPathBuf}; use paths::{AbsPath, AbsPathBuf};
@ -14,11 +14,11 @@ use crate::{
WorkspaceBuildScripts, WorkspaceBuildScripts,
}; };
fn load_cargo(file: &str) -> CrateGraph { fn load_cargo(file: &str) -> (CrateGraph, ProcMacros) {
load_cargo_with_overrides(file, CfgOverrides::default()) load_cargo_with_overrides(file, CfgOverrides::default())
} }
fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGraph { fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> (CrateGraph, ProcMacros) {
let meta = get_test_json_file(file); let meta = get_test_json_file(file);
let cargo_workspace = CargoWorkspace::new(meta); let cargo_workspace = CargoWorkspace::new(meta);
let project_workspace = ProjectWorkspace::Cargo { let project_workspace = ProjectWorkspace::Cargo {
@ -34,7 +34,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
to_crate_graph(project_workspace) to_crate_graph(project_workspace)
} }
fn load_rust_project(file: &str) -> CrateGraph { fn load_rust_project(file: &str) -> (CrateGraph, ProcMacros) {
let data = get_test_json_file(file); let data = get_test_json_file(file);
let project = rooted_project_json(data); let project = rooted_project_json(data);
let sysroot = Ok(get_fake_sysroot()); let sysroot = Ok(get_fake_sysroot());
@ -92,7 +92,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
ProjectJson::new(base, data) ProjectJson::new(base, data)
} }
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph { fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacros) {
project_workspace.to_crate_graph( project_workspace.to_crate_graph(
&mut |_, _| Ok(Vec::new()), &mut |_, _| Ok(Vec::new()),
&mut { &mut {
@ -117,7 +117,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
let cfg_overrides = CfgOverrides::Wildcard( let cfg_overrides = CfgOverrides::Wildcard(
CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(), CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(),
); );
let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides); let (crate_graph, _proc_macros) =
load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
check_crate_graph( check_crate_graph(
crate_graph, crate_graph,
expect![[r#" expect![[r#"
@ -184,9 +185,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -265,9 +263,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -346,9 +341,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -427,9 +419,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -498,9 +487,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -527,7 +513,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
.collect(), .collect(),
) )
}; };
let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides); let (crate_graph, _proc_macros) =
load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides);
check_crate_graph( check_crate_graph(
crate_graph, crate_graph,
expect![[r#" expect![[r#"
@ -596,9 +583,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -679,9 +663,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -762,9 +743,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -845,9 +823,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -916,9 +891,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -936,7 +908,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
#[test] #[test]
fn cargo_hello_world_project_model() { fn cargo_hello_world_project_model() {
let crate_graph = load_cargo("hello-world-metadata.json"); let (crate_graph, _proc_macros) = load_cargo("hello-world-metadata.json");
check_crate_graph( check_crate_graph(
crate_graph, crate_graph,
expect![[r#" expect![[r#"
@ -1005,9 +977,6 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -1088,9 +1057,6 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -1171,9 +1137,6 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -1254,9 +1217,6 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -1325,9 +1285,6 @@ fn cargo_hello_world_project_model() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"crate has not (yet) been built",
),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
"https://github.com/rust-lang/libc", "https://github.com/rust-lang/libc",
@ -1345,7 +1302,7 @@ fn cargo_hello_world_project_model() {
#[test] #[test]
fn rust_project_hello_world_project_model() { fn rust_project_hello_world_project_model() {
let crate_graph = load_rust_project("hello-world-project.json"); let (crate_graph, _proc_macros) = load_rust_project("hello-world-project.json");
check_crate_graph( check_crate_graph(
crate_graph, crate_graph,
expect![[r#" expect![[r#"
@ -1390,9 +1347,6 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Alloc, Alloc,
), ),
@ -1427,9 +1381,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Core, Core,
), ),
@ -1464,9 +1415,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1501,9 +1449,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1557,9 +1502,6 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1594,9 +1536,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1704,9 +1643,6 @@ fn rust_project_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Std, Std,
), ),
@ -1741,9 +1677,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1778,9 +1711,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Test, Test,
), ),
@ -1815,9 +1745,6 @@ fn rust_project_hello_world_project_model() {
entries: {}, entries: {},
}, },
dependencies: [], dependencies: [],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
),
origin: Lang( origin: Lang(
Other, Other,
), ),
@ -1889,9 +1816,6 @@ fn rust_project_hello_world_project_model() {
prelude: false, prelude: false,
}, },
], ],
proc_macro: Err(
"no proc macro dylib present",
),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
name: Some( name: Some(
@ -1907,7 +1831,7 @@ fn rust_project_hello_world_project_model() {
#[test] #[test]
fn rust_project_is_proc_macro_has_proc_macro_dep() { fn rust_project_is_proc_macro_has_proc_macro_dep() {
let crate_graph = load_rust_project("is-proc-macro-project.json"); let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
// Since the project only defines one crate (outside the sysroot crates), // Since the project only defines one crate (outside the sysroot crates),
// it should be the one with the biggest Id. // it should be the one with the biggest Id.
let crate_id = crate_graph.iter().max().unwrap(); let crate_id = crate_graph.iter().max().unwrap();

View File

@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, process::Command, sync::Arc};
use anyhow::{bail, format_err, Context, Result}; use anyhow::{bail, format_err, Context, Result};
use base_db::{ use base_db::{
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env,
FileId, LangCrateOrigin, ProcMacroLoadResult, TargetLayoutLoadResult, FileId, LangCrateOrigin, ProcMacroLoadResult, ProcMacros, TargetLayoutLoadResult,
}; };
use cfg::{CfgDiff, CfgOptions}; use cfg::{CfgDiff, CfgOptions};
use paths::{AbsPath, AbsPathBuf}; use paths::{AbsPath, AbsPathBuf};
@ -579,10 +579,10 @@ impl ProjectWorkspace {
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult, load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
) -> CrateGraph { ) -> (CrateGraph, ProcMacros) {
let _p = profile::span("ProjectWorkspace::to_crate_graph"); let _p = profile::span("ProjectWorkspace::to_crate_graph");
let mut crate_graph = match self { let (mut crate_graph, proc_macros) = match self {
ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph( ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph(
rustc_cfg.clone(), rustc_cfg.clone(),
load_proc_macro, load_proc_macro,
@ -630,7 +630,7 @@ impl ProjectWorkspace {
} else { } else {
tracing::debug!("Did not patch std to depend on cfg-if") tracing::debug!("Did not patch std to depend on cfg-if")
} }
crate_graph (crate_graph, proc_macros)
} }
pub fn eq_ignore_build_data(&self, other: &Self) -> bool { pub fn eq_ignore_build_data(&self, other: &Self) -> bool {
@ -685,8 +685,9 @@ fn project_json_to_crate_graph(
sysroot: Option<&Sysroot>, sysroot: Option<&Sysroot>,
extra_env: &FxHashMap<String, String>, extra_env: &FxHashMap<String, String>,
target_layout: TargetLayoutLoadResult, target_layout: TargetLayoutLoadResult,
) -> CrateGraph { ) -> (CrateGraph, ProcMacros) {
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
let mut proc_macros = FxHashMap::<_, _>::default();
let sysroot_deps = sysroot.as_ref().map(|sysroot| { let sysroot_deps = sysroot.as_ref().map(|sysroot| {
sysroot_to_crate_graph( sysroot_to_crate_graph(
&mut crate_graph, &mut crate_graph,
@ -707,13 +708,15 @@ fn project_json_to_crate_graph(
}) })
.map(|(crate_id, krate, file_id)| { .map(|(crate_id, krate, file_id)| {
let env = krate.env.clone().into_iter().collect(); let env = krate.env.clone().into_iter().collect();
let proc_macro = match krate.proc_macro_dylib_path.clone() { if let Some(it) = krate.proc_macro_dylib_path.clone() {
Some(it) => load_proc_macro( proc_macros.insert(
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""), crate_id,
&it, load_proc_macro(
), krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
None => Err("no proc macro dylib present".into()), &it,
}; ),
);
}
let target_cfgs = match krate.target.as_deref() { let target_cfgs = match krate.target.as_deref() {
Some(target) => cfg_cache Some(target) => cfg_cache
@ -734,7 +737,6 @@ fn project_json_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options, cfg_options,
env, env,
proc_macro,
krate.is_proc_macro, krate.is_proc_macro,
if krate.display_name.is_some() { if krate.display_name.is_some() {
CrateOrigin::CratesIo { CrateOrigin::CratesIo {
@ -776,7 +778,7 @@ fn project_json_to_crate_graph(
} }
} }
} }
crate_graph (crate_graph, proc_macros)
} }
fn cargo_to_crate_graph( fn cargo_to_crate_graph(
@ -789,9 +791,10 @@ fn cargo_to_crate_graph(
override_cfg: &CfgOverrides, override_cfg: &CfgOverrides,
build_scripts: &WorkspaceBuildScripts, build_scripts: &WorkspaceBuildScripts,
target_layout: TargetLayoutLoadResult, target_layout: TargetLayoutLoadResult,
) -> CrateGraph { ) -> (CrateGraph, ProcMacros) {
let _p = profile::span("cargo_to_crate_graph"); let _p = profile::span("cargo_to_crate_graph");
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
let mut proc_macros = FxHashMap::default();
let (public_deps, libproc_macro) = match sysroot { let (public_deps, libproc_macro) = match sysroot {
Some(sysroot) => sysroot_to_crate_graph( Some(sysroot) => sysroot_to_crate_graph(
&mut crate_graph, &mut crate_graph,
@ -855,6 +858,7 @@ fn cargo_to_crate_graph(
if let Some(file_id) = load(&cargo[tgt].root) { if let Some(file_id) = load(&cargo[tgt].root) {
let crate_id = add_target_crate_root( let crate_id = add_target_crate_root(
&mut crate_graph, &mut crate_graph,
&mut proc_macros,
&cargo[pkg], &cargo[pkg],
build_scripts.get_output(pkg), build_scripts.get_output(pkg),
cfg_options.clone(), cfg_options.clone(),
@ -931,6 +935,7 @@ fn cargo_to_crate_graph(
if let Some((rustc_workspace, rustc_build_scripts)) = rustc { if let Some((rustc_workspace, rustc_build_scripts)) = rustc {
handle_rustc_crates( handle_rustc_crates(
&mut crate_graph, &mut crate_graph,
&mut proc_macros,
&mut pkg_to_lib_crate, &mut pkg_to_lib_crate,
load, load,
load_proc_macro, load_proc_macro,
@ -952,7 +957,7 @@ fn cargo_to_crate_graph(
); );
} }
} }
crate_graph (crate_graph, proc_macros)
} }
fn detached_files_to_crate_graph( fn detached_files_to_crate_graph(
@ -961,7 +966,7 @@ fn detached_files_to_crate_graph(
detached_files: &[AbsPathBuf], detached_files: &[AbsPathBuf],
sysroot: Option<&Sysroot>, sysroot: Option<&Sysroot>,
target_layout: TargetLayoutLoadResult, target_layout: TargetLayoutLoadResult,
) -> CrateGraph { ) -> (CrateGraph, ProcMacros) {
let _p = profile::span("detached_files_to_crate_graph"); let _p = profile::span("detached_files_to_crate_graph");
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
let (public_deps, _libproc_macro) = match sysroot { let (public_deps, _libproc_macro) = match sysroot {
@ -998,7 +1003,6 @@ fn detached_files_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options.clone(), cfg_options.clone(),
Env::default(), Env::default(),
Ok(Vec::new()),
false, false,
CrateOrigin::CratesIo { CrateOrigin::CratesIo {
repo: None, repo: None,
@ -1009,11 +1013,12 @@ fn detached_files_to_crate_graph(
public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate); public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
} }
crate_graph (crate_graph, FxHashMap::default())
} }
fn handle_rustc_crates( fn handle_rustc_crates(
crate_graph: &mut CrateGraph, crate_graph: &mut CrateGraph,
proc_macros: &mut ProcMacros,
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>, pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult, load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
@ -1075,6 +1080,7 @@ fn handle_rustc_crates(
if let Some(file_id) = load(&rustc_workspace[tgt].root) { if let Some(file_id) = load(&rustc_workspace[tgt].root) {
let crate_id = add_target_crate_root( let crate_id = add_target_crate_root(
crate_graph, crate_graph,
proc_macros,
&rustc_workspace[pkg], &rustc_workspace[pkg],
build_scripts.get_output(pkg), build_scripts.get_output(pkg),
cfg_options.clone(), cfg_options.clone(),
@ -1140,6 +1146,7 @@ fn handle_rustc_crates(
fn add_target_crate_root( fn add_target_crate_root(
crate_graph: &mut CrateGraph, crate_graph: &mut CrateGraph,
proc_macros: &mut ProcMacros,
pkg: &PackageData, pkg: &PackageData,
build_data: Option<&BuildScriptOutput>, build_data: Option<&BuildScriptOutput>,
cfg_options: CfgOptions, cfg_options: CfgOptions,
@ -1176,14 +1183,8 @@ fn add_target_crate_root(
} }
} }
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
Some(Some(it)) => load_proc_macro(it),
Some(None) => Err("no proc macro dylib present".into()),
None => Err("crate has not (yet) been built".into()),
};
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());
crate_graph.add_crate_root( let crate_id = crate_graph.add_crate_root(
file_id, file_id,
edition, edition,
Some(display_name), Some(display_name),
@ -1191,11 +1192,19 @@ fn add_target_crate_root(
cfg_options, cfg_options,
potential_cfg_options, potential_cfg_options,
env, env,
proc_macro,
is_proc_macro, is_proc_macro,
CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) }, CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) },
target_layout, target_layout,
) );
let proc_macro = match build_data.as_ref().map(|it| &it.proc_macro_dylib_path) {
Some(it) => it.as_deref().map(load_proc_macro),
None => Some(Err("crate has not (yet) been built".into())),
};
if let Some(proc_macro) = proc_macro {
proc_macros.insert(crate_id, proc_macro);
}
crate_id
} }
#[derive(Default)] #[derive(Default)]
@ -1237,7 +1246,6 @@ fn sysroot_to_crate_graph(
cfg_options.clone(), cfg_options.clone(),
cfg_options.clone(), cfg_options.clone(),
env, env,
Err("no proc macro loaded for sysroot crate".into()),
false, false,
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)), CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
target_layout.clone(), target_layout.clone(),

View File

@ -6,7 +6,10 @@ use anyhow::Result;
use crossbeam_channel::{unbounded, Receiver}; use crossbeam_channel::{unbounded, Receiver};
use hir::db::DefDatabase; use hir::db::DefDatabase;
use ide::{AnalysisHost, Change}; use ide::{AnalysisHost, Change};
use ide_db::{base_db::CrateGraph, FxHashMap}; use ide_db::{
base_db::{CrateGraph, ProcMacros},
FxHashMap,
};
use proc_macro_api::ProcMacroServer; use proc_macro_api::ProcMacroServer;
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace}; use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use vfs::{loader::Handle, AbsPath, AbsPathBuf};
@ -79,7 +82,7 @@ pub fn load_workspace(
ProcMacroServerChoice::None => Err("proc macro server disabled".to_owned()), ProcMacroServerChoice::None => Err("proc macro server disabled".to_owned()),
}; };
let crate_graph = ws.to_crate_graph( let (crate_graph, proc_macros) = ws.to_crate_graph(
&mut |_, path: &AbsPath| { &mut |_, path: &AbsPath| {
load_proc_macro(proc_macro_client.as_ref().map_err(|e| &**e), path, &[]) load_proc_macro(proc_macro_client.as_ref().map_err(|e| &**e), path, &[])
}, },
@ -100,8 +103,13 @@ pub fn load_workspace(
}); });
tracing::debug!("crate graph: {:?}", crate_graph); tracing::debug!("crate graph: {:?}", crate_graph);
let host = let host = load_crate_graph(
load_crate_graph(crate_graph, project_folders.source_root_config, &mut vfs, &receiver); crate_graph,
proc_macros,
project_folders.source_root_config,
&mut vfs,
&receiver,
);
if load_config.prefill_caches { if load_config.prefill_caches {
host.analysis().parallel_prime_caches(1, |_| {})?; host.analysis().parallel_prime_caches(1, |_| {})?;
@ -111,6 +119,7 @@ pub fn load_workspace(
fn load_crate_graph( fn load_crate_graph(
crate_graph: CrateGraph, crate_graph: CrateGraph,
proc_macros: ProcMacros,
source_root_config: SourceRootConfig, source_root_config: SourceRootConfig,
vfs: &mut vfs::Vfs, vfs: &mut vfs::Vfs,
receiver: &Receiver<vfs::loader::Message>, receiver: &Receiver<vfs::loader::Message>,
@ -149,6 +158,7 @@ fn load_crate_graph(
analysis_change.set_roots(source_roots); analysis_change.set_roots(source_roots);
analysis_change.set_crate_graph(crate_graph); analysis_change.set_crate_graph(crate_graph);
analysis_change.set_proc_macros(proc_macros);
host.apply_change(analysis_change); host.apply_change(analysis_change);
host host

View File

@ -20,7 +20,7 @@ use ide::Change;
use ide_db::{ use ide_db::{
base_db::{ base_db::{
CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, CrateGraph, Env, ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind,
ProcMacroLoadResult, SourceRoot, VfsPath, ProcMacroLoadResult, ProcMacros, SourceRoot, VfsPath,
}, },
FxHashMap, FxHashMap,
}; };
@ -355,7 +355,7 @@ impl GlobalState {
}); });
// Create crate graph from all the workspaces // Create crate graph from all the workspaces
let crate_graph = { let (crate_graph, proc_macros) = {
let dummy_replacements = self.config.dummy_replacements(); let dummy_replacements = self.config.dummy_replacements();
let vfs = &mut self.vfs.write().0; let vfs = &mut self.vfs.write().0;
@ -376,6 +376,7 @@ impl GlobalState {
}; };
let mut crate_graph = CrateGraph::default(); let mut crate_graph = CrateGraph::default();
let mut proc_macros = ProcMacros::default();
for (idx, ws) in self.workspaces.iter().enumerate() { for (idx, ws) in self.workspaces.iter().enumerate() {
let proc_macro_client = match self.proc_macro_clients.get(idx) { let proc_macro_client = match self.proc_macro_clients.get(idx) {
Some(res) => res.as_ref().map_err(|e| &**e), Some(res) => res.as_ref().map_err(|e| &**e),
@ -388,15 +389,17 @@ impl GlobalState {
dummy_replacements.get(crate_name).map(|v| &**v).unwrap_or_default(), dummy_replacements.get(crate_name).map(|v| &**v).unwrap_or_default(),
) )
}; };
crate_graph.extend(ws.to_crate_graph( let (other, other_proc_macros) = ws.to_crate_graph(
&mut load_proc_macro, &mut load_proc_macro,
&mut load, &mut load,
&self.config.cargo().extra_env, &self.config.cargo().extra_env,
)); );
crate_graph.extend(other, &mut proc_macros, other_proc_macros);
} }
crate_graph (crate_graph, proc_macros)
}; };
change.set_crate_graph(crate_graph); change.set_crate_graph(crate_graph);
change.set_proc_macros(proc_macros);
self.source_root_config = project_folders.source_root_config; self.source_root_config = project_folders.source_root_config;