From 0d19ee1d70cff2605cecd51c45945371c9cd1f58 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 12:17:24 +0100 Subject: Simplify --- crates/project_model/src/workspace.rs | 26 ++++++++++---------------- crates/rust-analyzer/src/reload.rs | 6 +++++- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index dbf1dc5bf..886b586a3 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -200,23 +200,19 @@ impl ProjectWorkspace { let mut crate_graph = CrateGraph::default(); match self { ProjectWorkspace::Json { project, sysroot } => { - let sysroot_dps = sysroot + let sysroot_deps = sysroot .as_ref() .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); let mut cfg_cache: FxHashMap, Vec> = FxHashMap::default(); - let crates: FxHashMap<_, _> = project + let crates: FxHashMap = project .crates() .filter_map(|(crate_id, krate)| { let file_path = &krate.root_module; - let file_id = match load(&file_path) { - Some(id) => id, - None => { - log::error!("failed to load crate root {}", file_path.display()); - return None; - } - }; - + let file_id = load(&file_path)?; + Some((crate_id, krate, file_id)) + }) + .map(|(crate_id, krate, file_id)| { let env = krate.env.clone().into_iter().collect(); let proc_macro = krate .proc_macro_dylib_path @@ -230,8 +226,7 @@ impl ProjectWorkspace { let mut cfg_options = CfgOptions::default(); cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned()); - - Some(( + ( crate_id, crate_graph.add_crate_root( file_id, @@ -241,21 +236,20 @@ impl ProjectWorkspace { env, proc_macro.unwrap_or_default(), ), - )) + ) }) .collect(); for (from, krate) in project.crates() { if let Some(&from) = crates.get(&from) { - if let Some((public_deps, _proc_macro)) = &sysroot_dps { + if let Some((public_deps, _proc_macro)) = &sysroot_deps { for (name, to) in public_deps.iter() { add_dep(&mut crate_graph, from, name.clone(), *to) } } for dep in &krate.deps { - let to_crate_id = dep.crate_id; - if let Some(&to) = crates.get(&to_crate_id) { + if let Some(&to) = crates.get(&dep.crate_id) { add_dep(&mut crate_graph, from, dep.name.clone(), to) } } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index fa6e09f42..001bf5949 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -203,7 +203,11 @@ impl GlobalState { let contents = loader.handle.load_sync(path); vfs.set_file_contents(vfs_path.clone(), contents); } - vfs.file_id(&vfs_path) + let res = vfs.file_id(&vfs_path); + if res.is_none() { + log::error!("failed to load {}", path.display()) + } + res }; for ws in workspaces.iter() { crate_graph.extend(ws.to_crate_graph( -- cgit v1.2.3 From db218006c928d8de6e31f6faae4bbb21c33ba4eb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 12:19:04 +0100 Subject: Remove dead code --- crates/cfg/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index d0e08cf5f..d88ecf8b0 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -41,12 +41,6 @@ impl CfgOptions { self.enabled.insert(CfgAtom::KeyValue { key, value }); } - pub fn append(&mut self, other: &CfgOptions) { - for atom in &other.enabled { - self.enabled.insert(atom.clone()); - } - } - pub fn apply_diff(&mut self, diff: CfgDiff) { for atom in diff.enable { self.enabled.insert(atom); -- cgit v1.2.3 From a0c4dbc399ee11cc8c34e5ef33d7c3cba8a03d47 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 13:29:45 +0100 Subject: Minor --- crates/project_model/src/workspace.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 886b586a3..2155687ec 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -305,11 +305,11 @@ impl ProjectWorkspace { // Set deps to the core, std and to the lib target of the current package for &from in pkg_crates.get(&pkg).into_iter().flatten() { if let Some((to, name)) = lib_tgt.clone() { - // For root projects with dashes in their name, - // cargo metadata does not do any normalization, - // so we do it ourselves currently - let name = CrateName::normalize_dashes(&name); if to != from { + // For root projects with dashes in their name, + // cargo metadata does not do any normalization, + // so we do it ourselves currently + let name = CrateName::normalize_dashes(&name); add_dep(&mut crate_graph, from, name, to); } } -- cgit v1.2.3 From bd4d375a64e6ab58896ddcccb81e06dd5b4051d3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 13:35:25 +0100 Subject: Make code more readable --- crates/project_model/src/workspace.rs | 393 ++++++++++++++++++---------------- 1 file changed, 207 insertions(+), 186 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 2155687ec..3ea6ba47e 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -197,215 +197,236 @@ impl ProjectWorkspace { proc_macro_client: &ProcMacroClient, load: &mut dyn FnMut(&AbsPath) -> Option, ) -> CrateGraph { - let mut crate_graph = CrateGraph::default(); - match self { + let mut crate_graph = match self { ProjectWorkspace::Json { project, sysroot } => { - let sysroot_deps = sysroot - .as_ref() - .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); - - let mut cfg_cache: FxHashMap, Vec> = FxHashMap::default(); - let crates: FxHashMap = project - .crates() - .filter_map(|(crate_id, krate)| { - let file_path = &krate.root_module; - let file_id = load(&file_path)?; - Some((crate_id, krate, file_id)) - }) - .map(|(crate_id, krate, file_id)| { - let env = krate.env.clone().into_iter().collect(); - let proc_macro = krate - .proc_macro_dylib_path - .clone() - .map(|it| proc_macro_client.by_dylib_path(&it)); - - let target = krate.target.as_deref().or(target); - let target_cfgs = cfg_cache - .entry(target) - .or_insert_with(|| get_rustc_cfg_options(target)); - - let mut cfg_options = CfgOptions::default(); - cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned()); - ( - crate_id, - crate_graph.add_crate_root( - file_id, - krate.edition, - krate.display_name.clone(), - cfg_options, - env, - proc_macro.unwrap_or_default(), - ), - ) - }) - .collect(); - - for (from, krate) in project.crates() { - if let Some(&from) = crates.get(&from) { - if let Some((public_deps, _proc_macro)) = &sysroot_deps { - for (name, to) in public_deps.iter() { - add_dep(&mut crate_graph, from, name.clone(), *to) - } - } - - for dep in &krate.deps { - if let Some(&to) = crates.get(&dep.crate_id) { - add_dep(&mut crate_graph, from, dep.name.clone(), to) - } - } - } - } + project_json_to_crate_graph(target, proc_macro_client, load, project, sysroot) } ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { - let (public_deps, libproc_macro) = - sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load); + cargo_to_crate_graph(target, proc_macro_client, load, cargo, sysroot, rustc) + } + }; + if crate_graph.patch_cfg_if() { + log::debug!("Patched std to depend on cfg-if") + } else { + log::debug!("Did not patch std to depend on cfg-if") + } + crate_graph + } +} - let mut cfg_options = CfgOptions::default(); - cfg_options.extend(get_rustc_cfg_options(target)); +fn project_json_to_crate_graph( + target: Option<&str>, + proc_macro_client: &ProcMacroClient, + load: &mut dyn FnMut(&AbsPath) -> Option, + project: &ProjectJson, + sysroot: &Option, +) -> CrateGraph { + let mut crate_graph = CrateGraph::default(); + let sysroot_deps = sysroot + .as_ref() + .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); + + let mut cfg_cache: FxHashMap, Vec> = FxHashMap::default(); + let crates: FxHashMap = project + .crates() + .filter_map(|(crate_id, krate)| { + let file_path = &krate.root_module; + let file_id = load(&file_path)?; + Some((crate_id, krate, file_id)) + }) + .map(|(crate_id, krate, file_id)| { + let env = krate.env.clone().into_iter().collect(); + let proc_macro = + krate.proc_macro_dylib_path.clone().map(|it| proc_macro_client.by_dylib_path(&it)); + + let target = krate.target.as_deref().or(target); + let target_cfgs = + cfg_cache.entry(target).or_insert_with(|| get_rustc_cfg_options(target)); + + let mut cfg_options = CfgOptions::default(); + cfg_options.extend(target_cfgs.iter().chain(krate.cfg.iter()).cloned()); + ( + crate_id, + crate_graph.add_crate_root( + file_id, + krate.edition, + krate.display_name.clone(), + cfg_options, + env, + proc_macro.unwrap_or_default(), + ), + ) + }) + .collect(); - let mut pkg_to_lib_crate = FxHashMap::default(); + for (from, krate) in project.crates() { + if let Some(&from) = crates.get(&from) { + if let Some((public_deps, _proc_macro)) = &sysroot_deps { + for (name, to) in public_deps.iter() { + add_dep(&mut crate_graph, from, name.clone(), *to) + } + } - // Add test cfg for non-sysroot crates - cfg_options.insert_atom("test".into()); - cfg_options.insert_atom("debug_assertions".into()); + for dep in &krate.deps { + if let Some(&to) = crates.get(&dep.crate_id) { + add_dep(&mut crate_graph, from, dep.name.clone(), to) + } + } + } + } + crate_graph +} - let mut pkg_crates = FxHashMap::default(); +fn cargo_to_crate_graph( + target: Option<&str>, + proc_macro_client: &ProcMacroClient, + load: &mut dyn FnMut(&AbsPath) -> Option, + cargo: &CargoWorkspace, + sysroot: &Sysroot, + rustc: &Option, +) -> CrateGraph { + let mut crate_graph = CrateGraph::default(); + let (public_deps, libproc_macro) = + sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load); - // Next, create crates for each package, target pair - for pkg in cargo.packages() { - let mut lib_tgt = None; - for &tgt in cargo[pkg].targets.iter() { - if let Some(crate_id) = add_target_crate_root( + let mut cfg_options = CfgOptions::default(); + cfg_options.extend(get_rustc_cfg_options(target)); + + let mut pkg_to_lib_crate = FxHashMap::default(); + + // Add test cfg for non-sysroot crates + cfg_options.insert_atom("test".into()); + cfg_options.insert_atom("debug_assertions".into()); + + let mut pkg_crates = FxHashMap::default(); + + // Next, create crates for each package, target pair + for pkg in cargo.packages() { + let mut lib_tgt = None; + for &tgt in cargo[pkg].targets.iter() { + if let Some(crate_id) = add_target_crate_root( + &mut crate_graph, + &cargo[pkg], + &cargo[tgt], + &cfg_options, + proc_macro_client, + load, + ) { + if cargo[tgt].kind == TargetKind::Lib { + lib_tgt = Some((crate_id, cargo[tgt].name.clone())); + pkg_to_lib_crate.insert(pkg, crate_id); + } + if cargo[tgt].is_proc_macro { + if let Some(proc_macro) = libproc_macro { + add_dep( &mut crate_graph, - &cargo[pkg], - &cargo[tgt], - &cfg_options, - proc_macro_client, - load, - ) { - if cargo[tgt].kind == TargetKind::Lib { - lib_tgt = Some((crate_id, cargo[tgt].name.clone())); - pkg_to_lib_crate.insert(pkg, crate_id); - } - if cargo[tgt].is_proc_macro { - if let Some(proc_macro) = libproc_macro { - add_dep( - &mut crate_graph, - crate_id, - CrateName::new("proc_macro").unwrap(), - proc_macro, - ); - } - } - - pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); - } + crate_id, + CrateName::new("proc_macro").unwrap(), + proc_macro, + ); } + } - // Set deps to the core, std and to the lib target of the current package - for &from in pkg_crates.get(&pkg).into_iter().flatten() { - if let Some((to, name)) = lib_tgt.clone() { - if to != from { - // For root projects with dashes in their name, - // cargo metadata does not do any normalization, - // so we do it ourselves currently - let name = CrateName::normalize_dashes(&name); - add_dep(&mut crate_graph, from, name, to); - } - } - for (name, krate) in public_deps.iter() { - add_dep(&mut crate_graph, from, name.clone(), *krate); - } - } + pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); + } + } + + // Set deps to the core, std and to the lib target of the current package + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + if let Some((to, name)) = lib_tgt.clone() { + if to != from { + // For root projects with dashes in their name, + // cargo metadata does not do any normalization, + // so we do it ourselves currently + let name = CrateName::normalize_dashes(&name); + add_dep(&mut crate_graph, from, name, to); } + } + for (name, krate) in public_deps.iter() { + add_dep(&mut crate_graph, from, name.clone(), *krate); + } + } + } - // Now add a dep edge from all targets of upstream to the lib - // target of downstream. - for pkg in cargo.packages() { - for dep in cargo[pkg].dependencies.iter() { - let name = CrateName::new(&dep.name).unwrap(); - if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { - for &from in pkg_crates.get(&pkg).into_iter().flatten() { - add_dep(&mut crate_graph, from, name.clone(), to) - } - } - } + // Now add a dep edge from all targets of upstream to the lib + // target of downstream. + for pkg in cargo.packages() { + for dep in cargo[pkg].dependencies.iter() { + let name = CrateName::new(&dep.name).unwrap(); + if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + add_dep(&mut crate_graph, from, name.clone(), to) + } + } + } + } + + let mut rustc_pkg_crates = FxHashMap::default(); + + // If the user provided a path to rustc sources, we add all the rustc_private crates + // and create dependencies on them for the crates in the current workspace + if let Some(rustc_workspace) = rustc { + for pkg in rustc_workspace.packages() { + for &tgt in rustc_workspace[pkg].targets.iter() { + if rustc_workspace[tgt].kind != TargetKind::Lib { + continue; + } + // Exclude alloc / core / std + if rustc_workspace[tgt] + .root + .components() + .any(|c| c == Component::Normal("library".as_ref())) + { + continue; } - let mut rustc_pkg_crates = FxHashMap::default(); - - // If the user provided a path to rustc sources, we add all the rustc_private crates - // and create dependencies on them for the crates in the current workspace - if let Some(rustc_workspace) = rustc { - for pkg in rustc_workspace.packages() { - for &tgt in rustc_workspace[pkg].targets.iter() { - if rustc_workspace[tgt].kind != TargetKind::Lib { - continue; - } - // Exclude alloc / core / std - if rustc_workspace[tgt] - .root - .components() - .any(|c| c == Component::Normal("library".as_ref())) - { - continue; - } - - if let Some(crate_id) = add_target_crate_root( - &mut crate_graph, - &rustc_workspace[pkg], - &rustc_workspace[tgt], - &cfg_options, - proc_macro_client, - load, - ) { - pkg_to_lib_crate.insert(pkg, crate_id); - // Add dependencies on the core / std / alloc for rustc - for (name, krate) in public_deps.iter() { - add_dep(&mut crate_graph, crate_id, name.clone(), *krate); - } - rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); - } - } + if let Some(crate_id) = add_target_crate_root( + &mut crate_graph, + &rustc_workspace[pkg], + &rustc_workspace[tgt], + &cfg_options, + proc_macro_client, + load, + ) { + pkg_to_lib_crate.insert(pkg, crate_id); + // Add dependencies on the core / std / alloc for rustc + for (name, krate) in public_deps.iter() { + add_dep(&mut crate_graph, crate_id, name.clone(), *krate); } - // Now add a dep edge from all targets of upstream to the lib - // target of downstream. - for pkg in rustc_workspace.packages() { - for dep in rustc_workspace[pkg].dependencies.iter() { - let name = CrateName::new(&dep.name).unwrap(); - if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { - for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { - add_dep(&mut crate_graph, from, name.clone(), to); - } - } - } + rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); + } + } + } + // Now add a dep edge from all targets of upstream to the lib + // target of downstream. + for pkg in rustc_workspace.packages() { + for dep in rustc_workspace[pkg].dependencies.iter() { + let name = CrateName::new(&dep.name).unwrap(); + if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { + for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { + add_dep(&mut crate_graph, from, name.clone(), to); } + } + } + } + + // Add dependencies for all the crates of the current workspace to rustc_private libraries + for dep in rustc_workspace.packages() { + let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); - // Add dependencies for all the crates of the current workspace to rustc_private libraries - for dep in rustc_workspace.packages() { - let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); - - if let Some(&to) = pkg_to_lib_crate.get(&dep) { - for pkg in cargo.packages() { - if !cargo[pkg].is_member { - continue; - } - for &from in pkg_crates.get(&pkg).into_iter().flatten() { - add_dep(&mut crate_graph, from, name.clone(), to); - } - } - } + if let Some(&to) = pkg_to_lib_crate.get(&dep) { + for pkg in cargo.packages() { + if !cargo[pkg].is_member { + continue; + } + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + add_dep(&mut crate_graph, from, name.clone(), to); } } } } - if crate_graph.patch_cfg_if() { - log::debug!("Patched std to depend on cfg-if") - } else { - log::debug!("Did not patch std to depend on cfg-if") - } - crate_graph } + crate_graph } fn add_target_crate_root( -- cgit v1.2.3 From e88b5fe916802a1c3e3bc9685971439e7ad07fa8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Nov 2020 15:25:46 +0100 Subject: Simplify --- crates/project_model/src/workspace.rs | 104 ++++++++++++++++------------------ 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 3ea6ba47e..a71f96164 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -304,14 +304,14 @@ fn cargo_to_crate_graph( for pkg in cargo.packages() { let mut lib_tgt = None; for &tgt in cargo[pkg].targets.iter() { - if let Some(crate_id) = add_target_crate_root( - &mut crate_graph, - &cargo[pkg], - &cargo[tgt], - &cfg_options, - proc_macro_client, - load, - ) { + if let Some(file_id) = load(&cargo[tgt].root) { + let crate_id = add_target_crate_root( + &mut crate_graph, + &cargo[pkg], + &cfg_options, + proc_macro_client, + file_id, + ); if cargo[tgt].kind == TargetKind::Lib { lib_tgt = Some((crate_id, cargo[tgt].name.clone())); pkg_to_lib_crate.insert(pkg, crate_id); @@ -380,14 +380,14 @@ fn cargo_to_crate_graph( continue; } - if let Some(crate_id) = add_target_crate_root( - &mut crate_graph, - &rustc_workspace[pkg], - &rustc_workspace[tgt], - &cfg_options, - proc_macro_client, - load, - ) { + if let Some(file_id) = load(&rustc_workspace[tgt].root) { + let crate_id = add_target_crate_root( + &mut crate_graph, + &rustc_workspace[pkg], + &cfg_options, + proc_macro_client, + file_id, + ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on the core / std / alloc for rustc for (name, krate) in public_deps.iter() { @@ -432,49 +432,45 @@ fn cargo_to_crate_graph( fn add_target_crate_root( crate_graph: &mut CrateGraph, pkg: &cargo_workspace::PackageData, - tgt: &cargo_workspace::TargetData, cfg_options: &CfgOptions, proc_macro_client: &ProcMacroClient, - load: &mut dyn FnMut(&AbsPath) -> Option, -) -> Option { - let root = tgt.root.as_path(); - if let Some(file_id) = load(root) { - let edition = pkg.edition; - let cfg_options = { - let mut opts = cfg_options.clone(); - for feature in pkg.features.iter() { - opts.insert_key_value("feature".into(), feature.into()); - } - opts.extend(pkg.cfgs.iter().cloned()); - opts - }; - let mut env = Env::default(); - if let Some(out_dir) = &pkg.out_dir { - // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!() - if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) { - env.set("OUT_DIR", out_dir); - } + file_id: FileId, +) -> CrateId { + let edition = pkg.edition; + let cfg_options = { + let mut opts = cfg_options.clone(); + for feature in pkg.features.iter() { + opts.insert_key_value("feature".into(), feature.into()); + } + opts.extend(pkg.cfgs.iter().cloned()); + opts + }; + let mut env = Env::default(); + if let Some(out_dir) = &pkg.out_dir { + // NOTE: cargo and rustc seem to hide non-UTF-8 strings from env! and option_env!() + if let Some(out_dir) = out_dir.to_str().map(|s| s.to_owned()) { + env.set("OUT_DIR", out_dir); } - let proc_macro = pkg - .proc_macro_dylib_path - .as_ref() - .map(|it| proc_macro_client.by_dylib_path(&it)) - .unwrap_or_default(); - - let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); - let crate_id = crate_graph.add_crate_root( - file_id, - edition, - Some(display_name), - cfg_options, - env, - proc_macro.clone(), - ); - - return Some(crate_id); } - None + let proc_macro = pkg + .proc_macro_dylib_path + .as_ref() + .map(|it| proc_macro_client.by_dylib_path(&it)) + .unwrap_or_default(); + + let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); + let crate_id = crate_graph.add_crate_root( + file_id, + edition, + Some(display_name), + cfg_options, + env, + proc_macro.clone(), + ); + + crate_id } + fn sysroot_to_crate_graph( crate_graph: &mut CrateGraph, sysroot: &Sysroot, -- cgit v1.2.3