aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model/src/workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/project_model/src/workspace.rs')
-rw-r--r--crates/project_model/src/workspace.rs79
1 files changed, 61 insertions, 18 deletions
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 8e0481ae9..0220efdb4 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -16,8 +16,13 @@ use proc_macro_api::ProcMacroClient;
16use rustc_hash::{FxHashMap, FxHashSet}; 16use rustc_hash::{FxHashMap, FxHashSet};
17 17
18use crate::{ 18use crate::{
19 cargo_workspace, cfg_flag::CfgFlag, rustc_cfg, sysroot::SysrootCrate, utf8_stdout, CargoConfig, 19 build_data::{BuildData, BuildDataMap, BuildDataResult},
20 CargoWorkspace, ProjectJson, ProjectManifest, Sysroot, TargetKind, 20 cargo_workspace,
21 cfg_flag::CfgFlag,
22 rustc_cfg,
23 sysroot::SysrootCrate,
24 utf8_stdout, BuildDataCollector, CargoConfig, CargoWorkspace, ProjectJson, ProjectManifest,
25 Sysroot, TargetKind,
21}; 26};
22 27
23/// `PackageRoot` describes a package root folder. 28/// `PackageRoot` describes a package root folder.
@@ -51,6 +56,7 @@ pub enum ProjectWorkspace {
51 56
52impl fmt::Debug for ProjectWorkspace { 57impl fmt::Debug for ProjectWorkspace {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 // Make sure this isn't too verbose.
54 match self { 60 match self {
55 ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => f 61 ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => f
56 .debug_struct("Cargo") 62 .debug_struct("Cargo")
@@ -60,7 +66,7 @@ impl fmt::Debug for ProjectWorkspace {
60 "n_rustc_compiler_crates", 66 "n_rustc_compiler_crates",
61 &rustc.as_ref().map_or(0, |rc| rc.packages().len()), 67 &rustc.as_ref().map_or(0, |rc| rc.packages().len()),
62 ) 68 )
63 .field("rustc_cfg", rustc_cfg) 69 .field("n_rustc_cfg", &rustc_cfg.len())
64 .finish(), 70 .finish(),
65 ProjectWorkspace::Json { project, sysroot, rustc_cfg } => { 71 ProjectWorkspace::Json { project, sysroot, rustc_cfg } => {
66 let mut debug_struct = f.debug_struct("Json"); 72 let mut debug_struct = f.debug_struct("Json");
@@ -68,7 +74,7 @@ impl fmt::Debug for ProjectWorkspace {
68 if let Some(sysroot) = sysroot { 74 if let Some(sysroot) = sysroot {
69 debug_struct.field("n_sysroot_crates", &sysroot.crates().len()); 75 debug_struct.field("n_sysroot_crates", &sysroot.crates().len());
70 } 76 }
71 debug_struct.field("rustc_cfg", rustc_cfg); 77 debug_struct.field("n_rustc_cfg", &rustc_cfg.len());
72 debug_struct.finish() 78 debug_struct.finish()
73 } 79 }
74 } 80 }
@@ -108,6 +114,7 @@ impl ProjectWorkspace {
108 cargo_version 114 cargo_version
109 ) 115 )
110 })?; 116 })?;
117
111 let sysroot = if config.no_sysroot { 118 let sysroot = if config.no_sysroot {
112 Sysroot::default() 119 Sysroot::default()
113 } else { 120 } else {
@@ -119,7 +126,17 @@ impl ProjectWorkspace {
119 })? 126 })?
120 }; 127 };
121 128
122 let rustc = if let Some(rustc_dir) = &config.rustc_source { 129 let rustc_dir = if let Some(rustc_source) = &config.rustc_source {
130 use cargo_workspace::RustcSource;
131 match rustc_source {
132 RustcSource::Path(path) => Some(path.clone()),
133 RustcSource::Discover => Sysroot::discover_rustc(&cargo_toml),
134 }
135 } else {
136 None
137 };
138
139 let rustc = if let Some(rustc_dir) = rustc_dir {
123 Some( 140 Some(
124 CargoWorkspace::from_cargo_metadata(&rustc_dir, config, progress) 141 CargoWorkspace::from_cargo_metadata(&rustc_dir, config, progress)
125 .with_context(|| { 142 .with_context(|| {
@@ -152,7 +169,7 @@ impl ProjectWorkspace {
152 /// Returns the roots for the current `ProjectWorkspace` 169 /// Returns the roots for the current `ProjectWorkspace`
153 /// The return type contains the path and whether or not 170 /// The return type contains the path and whether or not
154 /// the root is a member of the current workspace 171 /// the root is a member of the current workspace
155 pub fn to_roots(&self) -> Vec<PackageRoot> { 172 pub fn to_roots(&self, build_data: Option<&BuildDataResult>) -> Vec<PackageRoot> {
156 match self { 173 match self {
157 ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project 174 ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project
158 .crates() 175 .crates()
@@ -178,7 +195,12 @@ impl ProjectWorkspace {
178 let pkg_root = cargo[pkg].root().to_path_buf(); 195 let pkg_root = cargo[pkg].root().to_path_buf();
179 196
180 let mut include = vec![pkg_root.clone()]; 197 let mut include = vec![pkg_root.clone()];
181 include.extend(cargo[pkg].out_dir.clone()); 198 include.extend(
199 build_data
200 .and_then(|it| it.get(cargo.workspace_root()))
201 .and_then(|map| map.get(&cargo[pkg].id))
202 .and_then(|it| it.out_dir.clone()),
203 );
182 204
183 let mut exclude = vec![pkg_root.join(".git")]; 205 let mut exclude = vec![pkg_root.join(".git")];
184 if is_member { 206 if is_member {
@@ -218,6 +240,7 @@ impl ProjectWorkspace {
218 240
219 pub fn to_crate_graph( 241 pub fn to_crate_graph(
220 &self, 242 &self,
243 build_data: Option<&BuildDataResult>,
221 proc_macro_client: Option<&ProcMacroClient>, 244 proc_macro_client: Option<&ProcMacroClient>,
222 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, 245 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
223 ) -> CrateGraph { 246 ) -> CrateGraph {
@@ -240,8 +263,10 @@ impl ProjectWorkspace {
240 &proc_macro_loader, 263 &proc_macro_loader,
241 load, 264 load,
242 cargo, 265 cargo,
266 build_data.and_then(|it| it.get(cargo.workspace_root())),
243 sysroot, 267 sysroot,
244 rustc, 268 rustc,
269 rustc.as_ref().zip(build_data).and_then(|(it, map)| map.get(it.workspace_root())),
245 ), 270 ),
246 }; 271 };
247 if crate_graph.patch_cfg_if() { 272 if crate_graph.patch_cfg_if() {
@@ -251,6 +276,18 @@ impl ProjectWorkspace {
251 } 276 }
252 crate_graph 277 crate_graph
253 } 278 }
279
280 pub fn collect_build_data_configs(&self, collector: &mut BuildDataCollector) {
281 match self {
282 ProjectWorkspace::Cargo { cargo, rustc, .. } => {
283 collector.add_config(&cargo.workspace_root(), cargo.build_data_config().clone());
284 if let Some(rustc) = rustc {
285 collector.add_config(rustc.workspace_root(), rustc.build_data_config().clone());
286 }
287 }
288 _ => {}
289 }
290 }
254} 291}
255 292
256fn project_json_to_crate_graph( 293fn project_json_to_crate_graph(
@@ -323,8 +360,10 @@ fn cargo_to_crate_graph(
323 proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, 360 proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>,
324 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, 361 load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
325 cargo: &CargoWorkspace, 362 cargo: &CargoWorkspace,
363 build_data_map: Option<&BuildDataMap>,
326 sysroot: &Sysroot, 364 sysroot: &Sysroot,
327 rustc: &Option<CargoWorkspace>, 365 rustc: &Option<CargoWorkspace>,
366 rustc_build_data_map: Option<&BuildDataMap>,
328) -> CrateGraph { 367) -> CrateGraph {
329 let _p = profile::span("cargo_to_crate_graph"); 368 let _p = profile::span("cargo_to_crate_graph");
330 let mut crate_graph = CrateGraph::default(); 369 let mut crate_graph = CrateGraph::default();
@@ -350,6 +389,7 @@ fn cargo_to_crate_graph(
350 let crate_id = add_target_crate_root( 389 let crate_id = add_target_crate_root(
351 &mut crate_graph, 390 &mut crate_graph,
352 &cargo[pkg], 391 &cargo[pkg],
392 build_data_map.and_then(|it| it.get(&cargo[pkg].id)),
353 &cfg_options, 393 &cfg_options,
354 proc_macro_loader, 394 proc_macro_loader,
355 file_id, 395 file_id,
@@ -426,6 +466,7 @@ fn cargo_to_crate_graph(
426 let crate_id = add_target_crate_root( 466 let crate_id = add_target_crate_root(
427 &mut crate_graph, 467 &mut crate_graph,
428 &rustc_workspace[pkg], 468 &rustc_workspace[pkg],
469 rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)),
429 &cfg_options, 470 &cfg_options,
430 proc_macro_loader, 471 proc_macro_loader,
431 file_id, 472 file_id,
@@ -474,6 +515,7 @@ fn cargo_to_crate_graph(
474fn add_target_crate_root( 515fn add_target_crate_root(
475 crate_graph: &mut CrateGraph, 516 crate_graph: &mut CrateGraph,
476 pkg: &cargo_workspace::PackageData, 517 pkg: &cargo_workspace::PackageData,
518 build_data: Option<&BuildData>,
477 cfg_options: &CfgOptions, 519 cfg_options: &CfgOptions,
478 proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, 520 proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>,
479 file_id: FileId, 521 file_id: FileId,
@@ -481,26 +523,27 @@ fn add_target_crate_root(
481 let edition = pkg.edition; 523 let edition = pkg.edition;
482 let cfg_options = { 524 let cfg_options = {
483 let mut opts = cfg_options.clone(); 525 let mut opts = cfg_options.clone();
484 for feature in pkg.features.iter() { 526 for feature in pkg.active_features.iter() {
485 opts.insert_key_value("feature".into(), feature.into()); 527 opts.insert_key_value("feature".into(), feature.into());
486 } 528 }
487 opts.extend(pkg.cfgs.iter().cloned()); 529 if let Some(cfgs) = build_data.as_ref().map(|it| &it.cfgs) {
530 opts.extend(cfgs.iter().cloned());
531 }
488 opts 532 opts
489 }; 533 };
490 534
491 let mut env = Env::default(); 535 let mut env = Env::default();
492 for (k, v) in &pkg.envs { 536 if let Some(envs) = build_data.map(|it| &it.envs) {
493 env.set(k, v.clone()); 537 for (k, v) in envs {
494 } 538 env.set(k, v.clone());
495 if let Some(out_dir) = &pkg.out_dir {
496 // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!()
497 if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) {
498 env.set("OUT_DIR", out_dir);
499 } 539 }
500 } 540 }
501 541
502 let proc_macro = 542 let proc_macro = build_data
503 pkg.proc_macro_dylib_path.as_ref().map(|it| proc_macro_loader(&it)).unwrap_or_default(); 543 .as_ref()
544 .and_then(|it| it.proc_macro_dylib_path.as_ref())
545 .map(|it| proc_macro_loader(&it))
546 .unwrap_or_default();
504 547
505 let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); 548 let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone());
506 let crate_id = crate_graph.add_crate_root( 549 let crate_id = crate_graph.add_crate_root(