aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-08-25 16:53:24 +0100
committerAleksey Kladov <[email protected]>2020-08-25 16:53:24 +0100
commit7fcda5aa46808eed478defbd0494c6e11fee2ac6 (patch)
tree72113617219eeae9f16b324ae4bb33e49c8320d9
parent32be2d60af7c5c4706dc4ad4957056032d569643 (diff)
Prepare to share sysroot lowering code between Cargo & ProjectJSON
-rw-r--r--crates/project_model/src/lib.rs158
-rw-r--r--crates/project_model/src/sysroot.rs20
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
495fn 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
36impl Sysroot { 36impl 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 }