From 0e6922f8a8527ebddb553c66c4324fbc3ee97789 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 28 Sep 2021 21:39:41 +0200 Subject: [PATCH] Implicitly depend on `test` --- crates/project_model/src/sysroot.rs | 11 +++-- crates/project_model/src/tests.rs | 9 ++++ crates/project_model/src/workspace.rs | 64 ++++++++++++++++++--------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index 6c17492948..153cbc1c84 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs @@ -4,7 +4,7 @@ //! but we can't process `.rlib` and need source code instead. The source code //! is typically installed with `rustup component add rust-src` command. -use std::{convert::TryFrom, env, fs, ops, path::PathBuf, process::Command}; +use std::{convert::TryFrom, env, fs, iter, ops, path::PathBuf, process::Command}; use anyhow::{format_err, Result}; use la_arena::{Arena, Idx}; @@ -39,10 +39,15 @@ impl Sysroot { &self.root } - pub fn public_deps(&self) -> impl Iterator + '_ { + pub fn public_deps(&self) -> impl Iterator + '_ { // core is added as a dependency before std in order to // mimic rustcs dependency order - ["core", "alloc", "std"].iter().filter_map(move |&it| Some((it, self.by_name(it)?))) + ["core", "alloc", "std"] + .iter() + .copied() + .zip(iter::repeat(true)) + .chain(iter::once(("test", false))) + .filter_map(move |(name, prelude)| Some((name, self.by_name(name)?, prelude))) } pub fn proc_macro(&self) -> Option { diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs index 452ba18fe7..647d30605d 100644 --- a/crates/project_model/src/tests.rs +++ b/crates/project_model/src/tests.rs @@ -1690,6 +1690,15 @@ fn rust_project_hello_world_project_model() { ), prelude: true, }, + Dependency { + crate_id: CrateId( + 9, + ), + name: CrateName( + "test", + ), + prelude: false, + }, ], proc_macro: [], }, diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 225c7f9025..714e2dd301 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -470,9 +470,7 @@ fn project_json_to_crate_graph( for (from, krate) in project.crates() { if let Some(&from) = crates.get(&from) { if let Some((public_deps, libproc_macro)) = &sysroot_deps { - for (name, to) in public_deps.iter() { - add_dep(&mut crate_graph, from, name.clone(), *to) - } + public_deps.add(from, &mut crate_graph); if krate.is_proc_macro { if let Some(proc_macro) = libproc_macro { add_dep( @@ -509,7 +507,7 @@ fn cargo_to_crate_graph( let mut crate_graph = CrateGraph::default(); let (public_deps, libproc_macro) = match sysroot { Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load), - None => (Vec::new(), None), + None => (SysrootPublicDeps::default(), None), }; let mut cfg_options = CfgOptions::default(); @@ -590,9 +588,7 @@ fn cargo_to_crate_graph( add_dep(&mut crate_graph, *from, name, to); } } - for (name, krate) in public_deps.iter() { - add_dep(&mut crate_graph, *from, name.clone(), *krate); - } + public_deps.add(*from, &mut crate_graph); } } @@ -674,9 +670,7 @@ fn detached_files_to_crate_graph( Vec::new(), ); - for (name, krate) in public_deps.iter() { - add_dep(&mut crate_graph, detached_file_crate, name.clone(), *krate); - } + public_deps.add(detached_file_crate, &mut crate_graph); } crate_graph } @@ -688,7 +682,7 @@ fn handle_rustc_crates( cfg_options: &CfgOptions, load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, pkg_to_lib_crate: &mut FxHashMap, CrateId>, - public_deps: &[(CrateName, CrateId)], + public_deps: &SysrootPublicDeps, cargo: &CargoWorkspace, pkg_crates: &FxHashMap, Vec<(CrateId, TargetKind)>>, ) { @@ -728,9 +722,7 @@ fn handle_rustc_crates( ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on core / std / alloc for this crate - for (name, krate) in public_deps.iter() { - add_dep(crate_graph, crate_id, name.clone(), *krate); - } + public_deps.add(crate_id, crate_graph); rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); } } @@ -828,12 +820,26 @@ fn add_target_crate_root( ) } +#[derive(Default)] +struct SysrootPublicDeps { + deps: Vec<(CrateName, CrateId, bool)>, +} + +impl SysrootPublicDeps { + /// Makes `from` depend on the public sysroot crates. + fn add(&self, from: CrateId, crate_graph: &mut CrateGraph) { + for (name, krate, prelude) in &self.deps { + add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude); + } + } +} + fn sysroot_to_crate_graph( crate_graph: &mut CrateGraph, sysroot: &Sysroot, rustc_cfg: Vec, load: &mut dyn FnMut(&AbsPath) -> Option, -) -> (Vec<(CrateName, CrateId)>, Option) { +) -> (SysrootPublicDeps, Option) { let _p = profile::span("sysroot_to_crate_graph"); let mut cfg_options = CfgOptions::default(); cfg_options.extend(rustc_cfg); @@ -867,17 +873,35 @@ fn sysroot_to_crate_graph( } } - let public_deps = sysroot - .public_deps() - .map(|(name, idx)| (CrateName::new(name).unwrap(), sysroot_crates[&idx])) - .collect::>(); + let public_deps = SysrootPublicDeps { + deps: sysroot + .public_deps() + .map(|(name, idx, prelude)| { + (CrateName::new(name).unwrap(), sysroot_crates[&idx], prelude) + }) + .collect::>(), + }; let libproc_macro = sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); (public_deps, libproc_macro) } fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { - if let Err(err) = graph.add_dep(from, Dependency::new(name, to)) { + add_dep_inner(graph, from, Dependency::new(name, to)) +} + +fn add_dep_with_prelude( + graph: &mut CrateGraph, + from: CrateId, + name: CrateName, + to: CrateId, + prelude: bool, +) { + add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude)) +} + +fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) { + if let Err(err) = graph.add_dep(from, dep) { tracing::error!("{}", err) } }