diff options
author | Aleksey Kladov <[email protected]> | 2020-08-25 16:53:24 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-08-25 16:53:24 +0100 |
commit | 7fcda5aa46808eed478defbd0494c6e11fee2ac6 (patch) | |
tree | 72113617219eeae9f16b324ae4bb33e49c8320d9 | |
parent | 32be2d60af7c5c4706dc4ad4957056032d569643 (diff) |
Prepare to share sysroot lowering code between Cargo & ProjectJSON
-rw-r--r-- | crates/project_model/src/lib.rs | 158 | ||||
-rw-r--r-- | crates/project_model/src/sysroot.rs | 20 |
2 files changed, 73 insertions, 105 deletions
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index 2d65fc076..cbd4c5009 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs | |||
@@ -335,45 +335,8 @@ impl ProjectWorkspace { | |||
335 | let mut cfg_options = CfgOptions::default(); | 335 | let mut cfg_options = CfgOptions::default(); |
336 | cfg_options.extend(get_rustc_cfg_options(target)); | 336 | cfg_options.extend(get_rustc_cfg_options(target)); |
337 | 337 | ||
338 | let sysroot_crates: FxHashMap<_, _> = sysroot | 338 | let (public_deps, libproc_macro) = |
339 | .crates() | 339 | sysroot_to_crate_graph(&mut crate_graph, sysroot, &cfg_options, load); |
340 | .filter_map(|krate| { | ||
341 | let file_id = load(&sysroot[krate].root)?; | ||
342 | |||
343 | let env = Env::default(); | ||
344 | let proc_macro = vec![]; | ||
345 | let name = sysroot[krate].name.clone(); | ||
346 | let crate_id = crate_graph.add_crate_root( | ||
347 | file_id, | ||
348 | Edition::Edition2018, | ||
349 | Some(name), | ||
350 | cfg_options.clone(), | ||
351 | env, | ||
352 | proc_macro, | ||
353 | ); | ||
354 | Some((krate, crate_id)) | ||
355 | }) | ||
356 | .collect(); | ||
357 | |||
358 | for from in sysroot.crates() { | ||
359 | for &to in sysroot[from].deps.iter() { | ||
360 | let name = &sysroot[to].name; | ||
361 | if let (Some(&from), Some(&to)) = | ||
362 | (sysroot_crates.get(&from), sysroot_crates.get(&to)) | ||
363 | { | ||
364 | if crate_graph.add_dep(from, CrateName::new(name).unwrap(), to).is_err() | ||
365 | { | ||
366 | log::error!("cyclic dependency between sysroot crates") | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | } | ||
371 | |||
372 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); | ||
373 | let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied()); | ||
374 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); | ||
375 | let libproc_macro = | ||
376 | sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); | ||
377 | 340 | ||
378 | let mut pkg_to_lib_crate = FxHashMap::default(); | 341 | let mut pkg_to_lib_crate = FxHashMap::default(); |
379 | let mut pkg_crates = FxHashMap::default(); | 342 | let mut pkg_crates = FxHashMap::default(); |
@@ -424,14 +387,11 @@ impl ProjectWorkspace { | |||
424 | } | 387 | } |
425 | if cargo[tgt].is_proc_macro { | 388 | if cargo[tgt].is_proc_macro { |
426 | if let Some(proc_macro) = libproc_macro { | 389 | if let Some(proc_macro) = libproc_macro { |
427 | if crate_graph | 390 | if let Err(_) = crate_graph.add_dep( |
428 | .add_dep( | 391 | crate_id, |
429 | crate_id, | 392 | CrateName::new("proc_macro").unwrap(), |
430 | CrateName::new("proc_macro").unwrap(), | 393 | proc_macro, |
431 | proc_macro, | 394 | ) { |
432 | ) | ||
433 | .is_err() | ||
434 | { | ||
435 | log::error!( | 395 | log::error!( |
436 | "cyclic dependency on proc_macro for {}", | 396 | "cyclic dependency on proc_macro for {}", |
437 | &cargo[pkg].name | 397 | &cargo[pkg].name |
@@ -447,52 +407,22 @@ impl ProjectWorkspace { | |||
447 | // Set deps to the core, std and to the lib target of the current package | 407 | // Set deps to the core, std and to the lib target of the current package |
448 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 408 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
449 | if let Some((to, name)) = lib_tgt.clone() { | 409 | if let Some((to, name)) = lib_tgt.clone() { |
450 | if to != from | 410 | // For root projects with dashes in their name, |
451 | && crate_graph | 411 | // cargo metadata does not do any normalization, |
452 | .add_dep( | 412 | // so we do it ourselves currently |
453 | from, | 413 | let name = CrateName::normalize_dashes(&name); |
454 | // For root projects with dashes in their name, | 414 | if to != from && crate_graph.add_dep(from, name, to).is_err() { |
455 | // cargo metadata does not do any normalization, | 415 | log::error!( |
456 | // so we do it ourselves currently | 416 | "cyclic dependency between targets of {}", |
457 | CrateName::normalize_dashes(&name), | 417 | &cargo[pkg].name |
458 | to, | 418 | ) |
459 | ) | ||
460 | .is_err() | ||
461 | { | ||
462 | { | ||
463 | log::error!( | ||
464 | "cyclic dependency between targets of {}", | ||
465 | &cargo[pkg].name | ||
466 | ) | ||
467 | } | ||
468 | } | 419 | } |
469 | } | 420 | } |
470 | // core is added as a dependency before std in order to | 421 | for (name, krate) in public_deps.iter() { |
471 | // mimic rustcs dependency order | 422 | if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) { |
472 | if let Some(core) = libcore { | ||
473 | if crate_graph | ||
474 | .add_dep(from, CrateName::new("core").unwrap(), core) | ||
475 | .is_err() | ||
476 | { | ||
477 | log::error!("cyclic dependency on core for {}", &cargo[pkg].name) | 423 | log::error!("cyclic dependency on core for {}", &cargo[pkg].name) |
478 | } | 424 | } |
479 | } | 425 | } |
480 | if let Some(alloc) = liballoc { | ||
481 | if crate_graph | ||
482 | .add_dep(from, CrateName::new("alloc").unwrap(), alloc) | ||
483 | .is_err() | ||
484 | { | ||
485 | log::error!("cyclic dependency on alloc for {}", &cargo[pkg].name) | ||
486 | } | ||
487 | } | ||
488 | if let Some(std) = libstd { | ||
489 | if crate_graph | ||
490 | .add_dep(from, CrateName::new("std").unwrap(), std) | ||
491 | .is_err() | ||
492 | { | ||
493 | log::error!("cyclic dependency on std for {}", &cargo[pkg].name) | ||
494 | } | ||
495 | } | ||
496 | } | 426 | } |
497 | } | 427 | } |
498 | 428 | ||
@@ -500,12 +430,10 @@ impl ProjectWorkspace { | |||
500 | // target of downstream. | 430 | // target of downstream. |
501 | for pkg in cargo.packages() { | 431 | for pkg in cargo.packages() { |
502 | for dep in cargo[pkg].dependencies.iter() { | 432 | for dep in cargo[pkg].dependencies.iter() { |
433 | let name = CrateName::new(&dep.name).unwrap(); | ||
503 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 434 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
504 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 435 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
505 | if crate_graph | 436 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { |
506 | .add_dep(from, CrateName::new(&dep.name).unwrap(), to) | ||
507 | .is_err() | ||
508 | { | ||
509 | log::error!( | 437 | log::error!( |
510 | "cyclic dependency {} -> {}", | 438 | "cyclic dependency {} -> {}", |
511 | &cargo[pkg].name, | 439 | &cargo[pkg].name, |
@@ -563,3 +491,49 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> { | |||
563 | let stdout = String::from_utf8(output.stdout)?; | 491 | let stdout = String::from_utf8(output.stdout)?; |
564 | Ok(stdout.trim().to_string()) | 492 | Ok(stdout.trim().to_string()) |
565 | } | 493 | } |
494 | |||
495 | fn sysroot_to_crate_graph( | ||
496 | crate_graph: &mut CrateGraph, | ||
497 | sysroot: &Sysroot, | ||
498 | cfg_options: &CfgOptions, | ||
499 | load: &mut dyn FnMut(&AbsPath) -> Option<FileId>, | ||
500 | ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { | ||
501 | let sysroot_crates: FxHashMap<_, _> = sysroot | ||
502 | .crates() | ||
503 | .filter_map(|krate| { | ||
504 | let file_id = load(&sysroot[krate].root)?; | ||
505 | |||
506 | let env = Env::default(); | ||
507 | let proc_macro = vec![]; | ||
508 | let name = sysroot[krate].name.clone(); | ||
509 | let crate_id = crate_graph.add_crate_root( | ||
510 | file_id, | ||
511 | Edition::Edition2018, | ||
512 | Some(name), | ||
513 | cfg_options.clone(), | ||
514 | env, | ||
515 | proc_macro, | ||
516 | ); | ||
517 | Some((krate, crate_id)) | ||
518 | }) | ||
519 | .collect(); | ||
520 | |||
521 | for from in sysroot.crates() { | ||
522 | for &to in sysroot[from].deps.iter() { | ||
523 | let name = CrateName::new(&sysroot[to].name).unwrap(); | ||
524 | if let (Some(&from), Some(&to)) = (sysroot_crates.get(&from), sysroot_crates.get(&to)) { | ||
525 | if let Err(_) = crate_graph.add_dep(from, name, to) { | ||
526 | log::error!("cyclic dependency between sysroot crates") | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | |||
532 | let public_deps = sysroot | ||
533 | .public_deps() | ||
534 | .map(|(name, idx)| (CrateName::new(name).unwrap(), sysroot_crates[&idx])) | ||
535 | .collect::<Vec<_>>(); | ||
536 | |||
537 | let libproc_macro = sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); | ||
538 | (public_deps, libproc_macro) | ||
539 | } | ||
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index 687e15337..74c0eda9a 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs | |||
@@ -34,16 +34,10 @@ impl ops::Index<SysrootCrate> for Sysroot { | |||
34 | } | 34 | } |
35 | 35 | ||
36 | impl Sysroot { | 36 | impl Sysroot { |
37 | pub fn core(&self) -> Option<SysrootCrate> { | 37 | pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ { |
38 | self.by_name("core") | 38 | // core is added as a dependency before std in order to |
39 | } | 39 | // mimic rustcs dependency order |
40 | 40 | vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?))) | |
41 | pub fn alloc(&self) -> Option<SysrootCrate> { | ||
42 | self.by_name("alloc") | ||
43 | } | ||
44 | |||
45 | pub fn std(&self) -> Option<SysrootCrate> { | ||
46 | self.by_name("std") | ||
47 | } | 41 | } |
48 | 42 | ||
49 | pub fn proc_macro(&self) -> Option<SysrootCrate> { | 43 | pub fn proc_macro(&self) -> Option<SysrootCrate> { |
@@ -81,7 +75,7 @@ impl Sysroot { | |||
81 | } | 75 | } |
82 | } | 76 | } |
83 | 77 | ||
84 | if let Some(std) = sysroot.std() { | 78 | if let Some(std) = sysroot.by_name("std") { |
85 | for dep in STD_DEPS.trim().lines() { | 79 | for dep in STD_DEPS.trim().lines() { |
86 | if let Some(dep) = sysroot.by_name(dep) { | 80 | if let Some(dep) = sysroot.by_name(dep) { |
87 | sysroot.crates[std].deps.push(dep) | 81 | sysroot.crates[std].deps.push(dep) |
@@ -89,8 +83,8 @@ impl Sysroot { | |||
89 | } | 83 | } |
90 | } | 84 | } |
91 | 85 | ||
92 | if let Some(alloc) = sysroot.alloc() { | 86 | if let Some(alloc) = sysroot.by_name("alloc") { |
93 | if let Some(core) = sysroot.core() { | 87 | if let Some(core) = sysroot.by_name("core") { |
94 | sysroot.crates[alloc].deps.push(core); | 88 | sysroot.crates[alloc].deps.push(core); |
95 | } | 89 | } |
96 | } | 90 | } |