diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/project_model/src/cargo_workspace.rs | 3 | ||||
-rw-r--r-- | crates/project_model/src/lib.rs | 271 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 16 | ||||
-rw-r--r-- | crates/rust-analyzer/src/reload.rs | 4 |
4 files changed, 225 insertions, 69 deletions
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index d5f6a4025..608a031d4 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs | |||
@@ -64,6 +64,9 @@ pub struct CargoConfig { | |||
64 | 64 | ||
65 | /// rustc target | 65 | /// rustc target |
66 | pub target: Option<String>, | 66 | pub target: Option<String>, |
67 | |||
68 | /// rustc private crate source | ||
69 | pub rustc_source: Option<AbsPathBuf>, | ||
67 | } | 70 | } |
68 | 71 | ||
69 | pub type Package = Idx<PackageData>; | 72 | pub type Package = Idx<PackageData>; |
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index e92cfea59..4531b1928 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs | |||
@@ -9,6 +9,7 @@ use std::{ | |||
9 | fmt, | 9 | fmt, |
10 | fs::{self, read_dir, ReadDir}, | 10 | fs::{self, read_dir, ReadDir}, |
11 | io, | 11 | io, |
12 | path::Component, | ||
12 | process::Command, | 13 | process::Command, |
13 | }; | 14 | }; |
14 | 15 | ||
@@ -31,7 +32,7 @@ pub use proc_macro_api::ProcMacroClient; | |||
31 | #[derive(Clone, Eq, PartialEq)] | 32 | #[derive(Clone, Eq, PartialEq)] |
32 | pub enum ProjectWorkspace { | 33 | pub enum ProjectWorkspace { |
33 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. | 34 | /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. |
34 | Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, | 35 | Cargo { cargo: CargoWorkspace, sysroot: Sysroot, rustc: Option<CargoWorkspace> }, |
35 | /// Project workspace was manually specified using a `rust-project.json` file. | 36 | /// Project workspace was manually specified using a `rust-project.json` file. |
36 | Json { project: ProjectJson, sysroot: Option<Sysroot> }, | 37 | Json { project: ProjectJson, sysroot: Option<Sysroot> }, |
37 | } | 38 | } |
@@ -39,10 +40,14 @@ pub enum ProjectWorkspace { | |||
39 | impl fmt::Debug for ProjectWorkspace { | 40 | impl fmt::Debug for ProjectWorkspace { |
40 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 41 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
41 | match self { | 42 | match self { |
42 | ProjectWorkspace::Cargo { cargo, sysroot } => f | 43 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => f |
43 | .debug_struct("Cargo") | 44 | .debug_struct("Cargo") |
44 | .field("n_packages", &cargo.packages().len()) | 45 | .field("n_packages", &cargo.packages().len()) |
45 | .field("n_sysroot_crates", &sysroot.crates().len()) | 46 | .field("n_sysroot_crates", &sysroot.crates().len()) |
47 | .field( | ||
48 | "n_rustc_compiler_crates", | ||
49 | &rustc.as_ref().map_or(0, |rc| rc.packages().len()), | ||
50 | ) | ||
46 | .finish(), | 51 | .finish(), |
47 | ProjectWorkspace::Json { project, sysroot } => { | 52 | ProjectWorkspace::Json { project, sysroot } => { |
48 | let mut debug_struct = f.debug_struct("Json"); | 53 | let mut debug_struct = f.debug_struct("Json"); |
@@ -200,7 +205,19 @@ impl ProjectWorkspace { | |||
200 | } else { | 205 | } else { |
201 | Sysroot::default() | 206 | Sysroot::default() |
202 | }; | 207 | }; |
203 | ProjectWorkspace::Cargo { cargo, sysroot } | 208 | |
209 | let rustc = if let Some(rustc_dir) = &cargo_config.rustc_source { | ||
210 | Some( | ||
211 | CargoWorkspace::from_cargo_metadata(&rustc_dir, cargo_config) | ||
212 | .with_context(|| { | ||
213 | format!("Failed to read Cargo metadata for Rust sources") | ||
214 | })?, | ||
215 | ) | ||
216 | } else { | ||
217 | None | ||
218 | }; | ||
219 | |||
220 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } | ||
204 | } | 221 | } |
205 | }; | 222 | }; |
206 | 223 | ||
@@ -238,31 +255,43 @@ impl ProjectWorkspace { | |||
238 | }) | 255 | }) |
239 | })) | 256 | })) |
240 | .collect::<Vec<_>>(), | 257 | .collect::<Vec<_>>(), |
241 | ProjectWorkspace::Cargo { cargo, sysroot } => cargo | 258 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { |
242 | .packages() | 259 | let roots = cargo |
243 | .map(|pkg| { | 260 | .packages() |
244 | let is_member = cargo[pkg].is_member; | 261 | .map(|pkg| { |
245 | let pkg_root = cargo[pkg].root().to_path_buf(); | 262 | let is_member = cargo[pkg].is_member; |
246 | 263 | let pkg_root = cargo[pkg].root().to_path_buf(); | |
247 | let mut include = vec![pkg_root.clone()]; | 264 | |
248 | include.extend(cargo[pkg].out_dir.clone()); | 265 | let mut include = vec![pkg_root.clone()]; |
249 | 266 | include.extend(cargo[pkg].out_dir.clone()); | |
250 | let mut exclude = vec![pkg_root.join(".git")]; | 267 | |
251 | if is_member { | 268 | let mut exclude = vec![pkg_root.join(".git")]; |
252 | exclude.push(pkg_root.join("target")); | 269 | if is_member { |
253 | } else { | 270 | exclude.push(pkg_root.join("target")); |
254 | exclude.push(pkg_root.join("tests")); | 271 | } else { |
255 | exclude.push(pkg_root.join("examples")); | 272 | exclude.push(pkg_root.join("tests")); |
256 | exclude.push(pkg_root.join("benches")); | 273 | exclude.push(pkg_root.join("examples")); |
257 | } | 274 | exclude.push(pkg_root.join("benches")); |
258 | PackageRoot { is_member, include, exclude } | 275 | } |
259 | }) | 276 | PackageRoot { is_member, include, exclude } |
260 | .chain(sysroot.crates().map(|krate| PackageRoot { | 277 | }) |
261 | is_member: false, | 278 | .chain(sysroot.crates().map(|krate| PackageRoot { |
262 | include: vec![sysroot[krate].root_dir().to_path_buf()], | 279 | is_member: false, |
263 | exclude: Vec::new(), | 280 | include: vec![sysroot[krate].root_dir().to_path_buf()], |
264 | })) | 281 | exclude: Vec::new(), |
265 | .collect(), | 282 | })); |
283 | if let Some(rustc_packages) = rustc { | ||
284 | roots | ||
285 | .chain(rustc_packages.packages().map(|krate| PackageRoot { | ||
286 | is_member: false, | ||
287 | include: vec![rustc_packages[krate].root().to_path_buf()], | ||
288 | exclude: Vec::new(), | ||
289 | })) | ||
290 | .collect() | ||
291 | } else { | ||
292 | roots.collect() | ||
293 | } | ||
294 | } | ||
266 | } | 295 | } |
267 | } | 296 | } |
268 | 297 | ||
@@ -273,7 +302,7 @@ impl ProjectWorkspace { | |||
273 | .filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref()) | 302 | .filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref()) |
274 | .cloned() | 303 | .cloned() |
275 | .collect(), | 304 | .collect(), |
276 | ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo | 305 | ProjectWorkspace::Cargo { cargo, sysroot: _sysroot, rustc: _rustc_crates } => cargo |
277 | .packages() | 306 | .packages() |
278 | .filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref()) | 307 | .filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref()) |
279 | .cloned() | 308 | .cloned() |
@@ -284,8 +313,9 @@ impl ProjectWorkspace { | |||
284 | pub fn n_packages(&self) -> usize { | 313 | pub fn n_packages(&self) -> usize { |
285 | match self { | 314 | match self { |
286 | ProjectWorkspace::Json { project, .. } => project.n_crates(), | 315 | ProjectWorkspace::Json { project, .. } => project.n_crates(), |
287 | ProjectWorkspace::Cargo { cargo, sysroot } => { | 316 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { |
288 | cargo.packages().len() + sysroot.crates().len() | 317 | let rustc_package_len = rustc.as_ref().map_or(0, |rc| rc.packages().len()); |
318 | cargo.packages().len() + sysroot.crates().len() + rustc_package_len | ||
289 | } | 319 | } |
290 | } | 320 | } |
291 | } | 321 | } |
@@ -365,7 +395,7 @@ impl ProjectWorkspace { | |||
365 | } | 395 | } |
366 | } | 396 | } |
367 | } | 397 | } |
368 | ProjectWorkspace::Cargo { cargo, sysroot } => { | 398 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { |
369 | let (public_deps, libproc_macro) = | 399 | let (public_deps, libproc_macro) = |
370 | sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load); | 400 | sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load); |
371 | 401 | ||
@@ -373,50 +403,25 @@ impl ProjectWorkspace { | |||
373 | cfg_options.extend(get_rustc_cfg_options(target)); | 403 | cfg_options.extend(get_rustc_cfg_options(target)); |
374 | 404 | ||
375 | let mut pkg_to_lib_crate = FxHashMap::default(); | 405 | let mut pkg_to_lib_crate = FxHashMap::default(); |
376 | let mut pkg_crates = FxHashMap::default(); | ||
377 | 406 | ||
378 | // Add test cfg for non-sysroot crates | 407 | // Add test cfg for non-sysroot crates |
379 | cfg_options.insert_atom("test".into()); | 408 | cfg_options.insert_atom("test".into()); |
380 | cfg_options.insert_atom("debug_assertions".into()); | 409 | cfg_options.insert_atom("debug_assertions".into()); |
381 | 410 | ||
411 | let mut pkg_crates = FxHashMap::default(); | ||
412 | |||
382 | // Next, create crates for each package, target pair | 413 | // Next, create crates for each package, target pair |
383 | for pkg in cargo.packages() { | 414 | for pkg in cargo.packages() { |
384 | let mut lib_tgt = None; | 415 | let mut lib_tgt = None; |
385 | for &tgt in cargo[pkg].targets.iter() { | 416 | for &tgt in cargo[pkg].targets.iter() { |
386 | let root = cargo[tgt].root.as_path(); | 417 | if let Some(crate_id) = add_target_crate_root( |
387 | if let Some(file_id) = load(root) { | 418 | &mut crate_graph, |
388 | let edition = cargo[pkg].edition; | 419 | &cargo[pkg], |
389 | let cfg_options = { | 420 | &cargo[tgt], |
390 | let mut opts = cfg_options.clone(); | 421 | &cfg_options, |
391 | for feature in cargo[pkg].features.iter() { | 422 | proc_macro_client, |
392 | opts.insert_key_value("feature".into(), feature.into()); | 423 | load, |
393 | } | 424 | ) { |
394 | opts.extend(cargo[pkg].cfgs.iter().cloned()); | ||
395 | opts | ||
396 | }; | ||
397 | let mut env = Env::default(); | ||
398 | if let Some(out_dir) = &cargo[pkg].out_dir { | ||
399 | // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!() | ||
400 | if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) { | ||
401 | env.set("OUT_DIR", out_dir); | ||
402 | } | ||
403 | } | ||
404 | let proc_macro = cargo[pkg] | ||
405 | .proc_macro_dylib_path | ||
406 | .as_ref() | ||
407 | .map(|it| proc_macro_client.by_dylib_path(&it)) | ||
408 | .unwrap_or_default(); | ||
409 | |||
410 | let display_name = | ||
411 | CrateDisplayName::from_canonical_name(cargo[pkg].name.clone()); | ||
412 | let crate_id = crate_graph.add_crate_root( | ||
413 | file_id, | ||
414 | edition, | ||
415 | Some(display_name), | ||
416 | cfg_options, | ||
417 | env, | ||
418 | proc_macro.clone(), | ||
419 | ); | ||
420 | if cargo[tgt].kind == TargetKind::Lib { | 425 | if cargo[tgt].kind == TargetKind::Lib { |
421 | lib_tgt = Some((crate_id, cargo[tgt].name.clone())); | 426 | lib_tgt = Some((crate_id, cargo[tgt].name.clone())); |
422 | pkg_to_lib_crate.insert(pkg, crate_id); | 427 | pkg_to_lib_crate.insert(pkg, crate_id); |
@@ -484,6 +489,92 @@ impl ProjectWorkspace { | |||
484 | } | 489 | } |
485 | } | 490 | } |
486 | } | 491 | } |
492 | |||
493 | let mut rustc_pkg_crates = FxHashMap::default(); | ||
494 | |||
495 | // If the user provided a path to rustc sources, we add all the rustc_private crates | ||
496 | // and create dependencies on them for the crates in the current workspace | ||
497 | if let Some(rustc_workspace) = rustc { | ||
498 | for pkg in rustc_workspace.packages() { | ||
499 | for &tgt in rustc_workspace[pkg].targets.iter() { | ||
500 | if rustc_workspace[tgt].kind != TargetKind::Lib { | ||
501 | continue; | ||
502 | } | ||
503 | // Exclude alloc / core / std | ||
504 | if rustc_workspace[tgt] | ||
505 | .root | ||
506 | .components() | ||
507 | .any(|c| c == Component::Normal("library".as_ref())) | ||
508 | { | ||
509 | continue; | ||
510 | } | ||
511 | |||
512 | if let Some(crate_id) = add_target_crate_root( | ||
513 | &mut crate_graph, | ||
514 | &rustc_workspace[pkg], | ||
515 | &rustc_workspace[tgt], | ||
516 | &cfg_options, | ||
517 | proc_macro_client, | ||
518 | load, | ||
519 | ) { | ||
520 | pkg_to_lib_crate.insert(pkg, crate_id); | ||
521 | // Add dependencies on the core / std / alloc for rustc | ||
522 | for (name, krate) in public_deps.iter() { | ||
523 | if let Err(_) = | ||
524 | crate_graph.add_dep(crate_id, name.clone(), *krate) | ||
525 | { | ||
526 | log::error!( | ||
527 | "cyclic dependency on {} for {}", | ||
528 | name, | ||
529 | &cargo[pkg].name | ||
530 | ) | ||
531 | } | ||
532 | } | ||
533 | rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | // Now add a dep edge from all targets of upstream to the lib | ||
538 | // target of downstream. | ||
539 | for pkg in rustc_workspace.packages() { | ||
540 | for dep in rustc_workspace[pkg].dependencies.iter() { | ||
541 | let name = CrateName::new(&dep.name).unwrap(); | ||
542 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | ||
543 | for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { | ||
544 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { | ||
545 | log::error!( | ||
546 | "cyclic dependency {} -> {}", | ||
547 | &rustc_workspace[pkg].name, | ||
548 | &rustc_workspace[dep.pkg].name | ||
549 | ) | ||
550 | } | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | |||
556 | // Add dependencies for all the crates of the current workspace to rustc_private libraries | ||
557 | for dep in rustc_workspace.packages() { | ||
558 | let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); | ||
559 | |||
560 | if let Some(&to) = pkg_to_lib_crate.get(&dep) { | ||
561 | for pkg in cargo.packages() { | ||
562 | if !cargo[pkg].is_member { | ||
563 | continue; | ||
564 | } | ||
565 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | ||
566 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { | ||
567 | log::error!( | ||
568 | "cyclic dependency {} -> {}", | ||
569 | &cargo[pkg].name, | ||
570 | &rustc_workspace[dep].name | ||
571 | ) | ||
572 | } | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | } | ||
577 | } | ||
487 | } | 578 | } |
488 | } | 579 | } |
489 | if crate_graph.patch_cfg_if() { | 580 | if crate_graph.patch_cfg_if() { |
@@ -537,6 +628,52 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> { | |||
537 | Ok(stdout.trim().to_string()) | 628 | Ok(stdout.trim().to_string()) |
538 | } | 629 | } |
539 | 630 | ||
631 | fn add_target_crate_root( | ||
632 | crate_graph: &mut CrateGraph, | ||
633 | pkg: &cargo_workspace::PackageData, | ||
634 | tgt: &cargo_workspace::TargetData, | ||
635 | cfg_options: &CfgOptions, | ||
636 | proc_macro_client: &ProcMacroClient, | ||
637 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | ||
638 | ) -> Option<CrateId> { | ||
639 | let root = tgt.root.as_path(); | ||
640 | if let Some(file_id) = load(root) { | ||
641 | let edition = pkg.edition; | ||
642 | let cfg_options = { | ||
643 | let mut opts = cfg_options.clone(); | ||
644 | for feature in pkg.features.iter() { | ||
645 | opts.insert_key_value("feature".into(), feature.into()); | ||
646 | } | ||
647 | opts.extend(pkg.cfgs.iter().cloned()); | ||
648 | opts | ||
649 | }; | ||
650 | let mut env = Env::default(); | ||
651 | if let Some(out_dir) = &pkg.out_dir { | ||
652 | // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!() | ||
653 | if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) { | ||
654 | env.set("OUT_DIR", out_dir); | ||
655 | } | ||
656 | } | ||
657 | let proc_macro = pkg | ||
658 | .proc_macro_dylib_path | ||
659 | .as_ref() | ||
660 | .map(|it| proc_macro_client.by_dylib_path(&it)) | ||
661 | .unwrap_or_default(); | ||
662 | |||
663 | let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); | ||
664 | let crate_id = crate_graph.add_crate_root( | ||
665 | file_id, | ||
666 | edition, | ||
667 | Some(display_name), | ||
668 | cfg_options, | ||
669 | env, | ||
670 | proc_macro.clone(), | ||
671 | ); | ||
672 | |||
673 | return Some(crate_id); | ||
674 | } | ||
675 | None | ||
676 | } | ||
540 | fn sysroot_to_crate_graph( | 677 | fn sysroot_to_crate_graph( |
541 | crate_graph: &mut CrateGraph, | 678 | crate_graph: &mut CrateGraph, |
542 | sysroot: &Sysroot, | 679 | sysroot: &Sysroot, |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index b4c738272..74a021dbf 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | //! configure the server itself, feature flags are passed into analysis, and | 7 | //! configure the server itself, feature flags are passed into analysis, and |
8 | //! tweak things like automatic insertion of `()` in completions. | 8 | //! tweak things like automatic insertion of `()` in completions. |
9 | 9 | ||
10 | use std::{ffi::OsString, path::PathBuf}; | 10 | use std::{convert::TryFrom, ffi::OsString, path::PathBuf}; |
11 | 11 | ||
12 | use flycheck::FlycheckConfig; | 12 | use flycheck::FlycheckConfig; |
13 | use hir::PrefixKind; | 13 | use hir::PrefixKind; |
@@ -227,12 +227,25 @@ impl Config { | |||
227 | self.notifications = | 227 | self.notifications = |
228 | NotificationsConfig { cargo_toml_not_found: data.notifications_cargoTomlNotFound }; | 228 | NotificationsConfig { cargo_toml_not_found: data.notifications_cargoTomlNotFound }; |
229 | self.cargo_autoreload = data.cargo_autoreload; | 229 | self.cargo_autoreload = data.cargo_autoreload; |
230 | |||
231 | let rustc_source = if let Some(rustc_source) = data.rustcSource { | ||
232 | let rustpath: PathBuf = rustc_source.into(); | ||
233 | AbsPathBuf::try_from(rustpath) | ||
234 | .map_err(|_| { | ||
235 | log::error!("rustc source directory must be an absolute path"); | ||
236 | }) | ||
237 | .ok() | ||
238 | } else { | ||
239 | None | ||
240 | }; | ||
241 | |||
230 | self.cargo = CargoConfig { | 242 | self.cargo = CargoConfig { |
231 | no_default_features: data.cargo_noDefaultFeatures, | 243 | no_default_features: data.cargo_noDefaultFeatures, |
232 | all_features: data.cargo_allFeatures, | 244 | all_features: data.cargo_allFeatures, |
233 | features: data.cargo_features.clone(), | 245 | features: data.cargo_features.clone(), |
234 | load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck, | 246 | load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck, |
235 | target: data.cargo_target.clone(), | 247 | target: data.cargo_target.clone(), |
248 | rustc_source: rustc_source, | ||
236 | }; | 249 | }; |
237 | self.runnables = RunnablesConfig { | 250 | self.runnables = RunnablesConfig { |
238 | override_cargo: data.runnables_overrideCargo, | 251 | override_cargo: data.runnables_overrideCargo, |
@@ -535,5 +548,6 @@ config_data! { | |||
535 | rustfmt_overrideCommand: Option<Vec<String>> = None, | 548 | rustfmt_overrideCommand: Option<Vec<String>> = None, |
536 | 549 | ||
537 | withSysroot: bool = true, | 550 | withSysroot: bool = true, |
551 | rustcSource : Option<String> = None, | ||
538 | } | 552 | } |
539 | } | 553 | } |
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 0eabd51bd..11c8d0e5f 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -246,7 +246,9 @@ impl GlobalState { | |||
246 | .iter() | 246 | .iter() |
247 | .enumerate() | 247 | .enumerate() |
248 | .filter_map(|(id, w)| match w { | 248 | .filter_map(|(id, w)| match w { |
249 | ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some((id, cargo.workspace_root())), | 249 | ProjectWorkspace::Cargo { cargo, sysroot: _, rustc: _ } => { |
250 | Some((id, cargo.workspace_root())) | ||
251 | } | ||
250 | ProjectWorkspace::Json { project, .. } => { | 252 | ProjectWorkspace::Json { project, .. } => { |
251 | // Enable flychecks for json projects if a custom flycheck command was supplied | 253 | // Enable flychecks for json projects if a custom flycheck command was supplied |
252 | // in the workspace configuration. | 254 | // in the workspace configuration. |