From 1076d21fc0d86ae3b7bb7fca610548fedd42ab4a Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sat, 6 Mar 2021 12:17:22 +0000 Subject: [PATCH 01/12] Implement opt-in (and opt-out) rustc_private --- crates/project_model/src/cargo_workspace.rs | 23 +++++++++++++++++++-- crates/project_model/src/workspace.rs | 6 +++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index f7241b7113..beda2f61fa 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs @@ -9,6 +9,8 @@ use cargo_metadata::{CargoOpt, MetadataCommand}; use la_arena::{Arena, Idx}; use paths::{AbsPath, AbsPathBuf}; use rustc_hash::FxHashMap; +use serde::Deserialize; +use serde_json::from_value; use crate::build_data::BuildDataConfig; use crate::utf8_stdout; @@ -104,6 +106,13 @@ pub struct PackageData { pub active_features: Vec, // String representation of package id pub id: String, + // The contents of [package.metadata.rust-analyzer] + pub metadata: RustAnalyzerPackageMetaData, +} + +#[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)] +pub struct RustAnalyzerPackageMetaData { + pub rustc_private: Option, } #[derive(Debug, Clone, Eq, PartialEq)] @@ -161,6 +170,13 @@ impl PackageData { } } +#[derive(Deserialize, Default)] +// Deserialise helper for the cargo metadata +struct PackageMetadata { + #[serde(rename = "rust-analyzer")] + rust_analyzer: Option, +} + impl CargoWorkspace { pub fn from_cargo_metadata( cargo_toml: &AbsPath, @@ -244,8 +260,10 @@ impl CargoWorkspace { meta.packages.sort_by(|a, b| a.id.cmp(&b.id)); for meta_pkg in &meta.packages { - let cargo_metadata::Package { id, edition, name, manifest_path, version, .. } = - meta_pkg; + let cargo_metadata::Package { + id, edition, name, manifest_path, version, metadata, .. + } = meta_pkg; + let meta = from_value::(metadata.clone()).unwrap_or_default(); let is_member = ws_members.contains(&id); let edition = edition .parse::() @@ -262,6 +280,7 @@ impl CargoWorkspace { dependencies: Vec::new(), features: meta_pkg.features.clone().into_iter().collect(), active_features: Vec::new(), + metadata: meta.rust_analyzer.unwrap_or_default(), }); let pkg_data = &mut packages[pkg]; pkg_by_id.insert(id, pkg); diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 0220efdb4e..10e6085479 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -499,7 +499,11 @@ fn cargo_to_crate_graph( if let Some(&to) = pkg_to_lib_crate.get(&dep) { for pkg in cargo.packages() { - if !cargo[pkg].is_member { + let package = &cargo[pkg]; + if matches!( + (package.is_member, package.metadata.rustc_private), + (true, Some(false)) | (false, Some(false)) | (false, None) + ) { continue; } for &from in pkg_crates.get(&pkg).into_iter().flatten() { From 7513867aa21a638eac86c72c8eae0f9ba834380d Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sat, 6 Mar 2021 13:56:42 +0000 Subject: [PATCH 02/12] If a manual dependency exists, don't overwrite This is a hack to work around miri being included in our analysis of rustc-dev Really, we should probably use an include set of the actual root libraries I'm not sure how those are determined however --- crates/project_model/src/workspace.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 10e6085479..786d7e5ecc 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -507,7 +507,14 @@ fn cargo_to_crate_graph( continue; } for &from in pkg_crates.get(&pkg).into_iter().flatten() { - add_dep(&mut crate_graph, from, name.clone(), to); + if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { + add_dep(&mut crate_graph, from, name.clone(), to); + } else { + // eprintln!( + // "Skipped {} for {:?}", + // &name, &crate_graph[from].display_name + // ); + } } } } From b46605cfcd0cee5875a534371ee9b7ab648cd286 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 7 Mar 2021 10:18:01 +0000 Subject: [PATCH 03/12] Update crate graph to only use subcrates of rustc_driver --- crates/project_model/src/workspace.rs | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 786d7e5ecc..695fac3982 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -2,11 +2,7 @@ //! metadata` or `rust-project.json`) into representation stored in the salsa //! database -- `CrateGraph`. -use std::{ - fmt, fs, - path::{Component, Path}, - process::Command, -}; +use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; use anyhow::{Context, Result}; use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; @@ -446,37 +442,40 @@ fn cargo_to_crate_graph( 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 + // and create dependencies on them for the crates which opt-in to that 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; + // rustc-dev crates start from 'rustc_driver' + // Therefore, we collect all crates which are transitive dependencies of rustc_driver + if let Some(root_pkg) = rustc_workspace + .packages() + .find(|package| rustc_workspace[*package].name == "rustc_driver") + { + let mut queue = VecDeque::new(); + queue.push_back(root_pkg); + while let Some(pkg) = queue.pop_front() { + for dep in &rustc_workspace[pkg].dependencies { + queue.push_back(dep.pkg); } - // Exclude alloc / core / std - if rustc_workspace[tgt] - .root - .components() - .any(|c| c == Component::Normal("library".as_ref())) - { - continue; - } - - if let Some(file_id) = load(&rustc_workspace[tgt].root) { - let crate_id = add_target_crate_root( - &mut crate_graph, - &rustc_workspace[pkg], - rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), - &cfg_options, - proc_macro_loader, - 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() { - add_dep(&mut crate_graph, crate_id, name.clone(), *krate); + for &tgt in rustc_workspace[pkg].targets.iter() { + if rustc_workspace[tgt].kind != TargetKind::Lib { + continue; + } + if let Some(file_id) = load(&rustc_workspace[tgt].root) { + let crate_id = add_target_crate_root( + &mut crate_graph, + &rustc_workspace[pkg], + rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), + &cfg_options, + proc_macro_loader, + 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() { + add_dep(&mut crate_graph, crate_id, name.clone(), *krate); + } + rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); } - rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); } } } @@ -493,7 +492,7 @@ fn cargo_to_crate_graph( } } - // Add dependencies for all the crates of the current workspace to rustc_private libraries + // Add dependencies for all crates which opt in to rustc_private libraries for dep in rustc_workspace.packages() { let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); @@ -507,13 +506,14 @@ fn cargo_to_crate_graph( continue; } for &from in pkg_crates.get(&pkg).into_iter().flatten() { + // Avoid creating duplicate dependencies if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { add_dep(&mut crate_graph, from, name.clone(), to); } else { - // eprintln!( - // "Skipped {} for {:?}", - // &name, &crate_graph[from].display_name - // ); + eprintln!( + "Skipped {} for {:?}", + &name, &crate_graph[from].display_name + ); } } } From 71a254c1a1b8836db09dfd18a781c1a4215366fc Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 7 Mar 2021 11:17:14 +0000 Subject: [PATCH 04/12] Don't double analyse the same crate --- crates/project_model/src/workspace.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 695fac3982..cacf462cfe 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -453,6 +453,9 @@ fn cargo_to_crate_graph( let mut queue = VecDeque::new(); queue.push_back(root_pkg); while let Some(pkg) = queue.pop_front() { + if rustc_pkg_crates.contains_key(&pkg) { + continue; + } for dep in &rustc_workspace[pkg].dependencies { queue.push_back(dep.pkg); } @@ -481,7 +484,7 @@ fn cargo_to_crate_graph( } // Now add a dep edge from all targets of upstream to the lib // target of downstream. - for pkg in rustc_workspace.packages() { + for pkg in rustc_pkg_crates.keys().copied() { 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) { @@ -519,6 +522,8 @@ fn cargo_to_crate_graph( } } } + } else { + eprintln!("No cargo workspace"); } crate_graph } From 9246df669ae67556b66119c8a6e3416c9534ca45 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 7 Mar 2021 12:24:20 +0000 Subject: [PATCH 05/12] Require opt in to rustc_private This gives the advantage that A future extension would be to check for `feature(rustc_private)` instead --- crates/project_model/src/cargo_workspace.rs | 2 +- crates/project_model/src/workspace.rs | 150 ++++++++++---------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index beda2f61fa..bc6e203414 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs @@ -112,7 +112,7 @@ pub struct PackageData { #[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)] pub struct RustAnalyzerPackageMetaData { - pub rustc_private: Option, + pub rustc_private: bool, } #[derive(Debug, Clone, Eq, PartialEq)] diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index cacf462cfe..b969420cf3 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -376,9 +376,10 @@ fn cargo_to_crate_graph( cfg_options.insert_atom("debug_assertions".into()); let mut pkg_crates = FxHashMap::default(); - + let mut has_private = false; // Next, create crates for each package, target pair for pkg in cargo.packages() { + has_private |= cargo[pkg].metadata.rustc_private; let mut lib_tgt = None; for &tgt in cargo[pkg].targets.iter() { if let Some(file_id) = load(&cargo[tgt].root) { @@ -441,89 +442,88 @@ fn cargo_to_crate_graph( 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 which opt-in to that - if let Some(rustc_workspace) = rustc { - // rustc-dev crates start from 'rustc_driver' - // Therefore, we collect all crates which are transitive dependencies of rustc_driver - if let Some(root_pkg) = rustc_workspace - .packages() - .find(|package| rustc_workspace[*package].name == "rustc_driver") - { - let mut queue = VecDeque::new(); - queue.push_back(root_pkg); - while let Some(pkg) = queue.pop_front() { - if rustc_pkg_crates.contains_key(&pkg) { - continue; - } - for dep in &rustc_workspace[pkg].dependencies { - queue.push_back(dep.pkg); - } - for &tgt in rustc_workspace[pkg].targets.iter() { - if rustc_workspace[tgt].kind != TargetKind::Lib { + if has_private { + // If the user provided a path to rustc sources, we add all the rustc_private crates + // and create dependencies on them for the crates which opt-in to that + if let Some(rustc_workspace) = rustc { + // rustc-dev crates start from 'rustc_driver' + // We want to collect all crates which are transitive dependencies of rustc_driver + if let Some(root_pkg) = rustc_workspace + .packages() + .find(|package| rustc_workspace[*package].name == "rustc_driver") + { + let mut queue = VecDeque::new(); + queue.push_back(root_pkg); + while let Some(pkg) = queue.pop_front() { + // Don't duplicate packages + if rustc_pkg_crates.contains_key(&pkg) { continue; } - if let Some(file_id) = load(&rustc_workspace[tgt].root) { - let crate_id = add_target_crate_root( - &mut crate_graph, - &rustc_workspace[pkg], - rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), - &cfg_options, - proc_macro_loader, - 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() { - add_dep(&mut crate_graph, crate_id, name.clone(), *krate); + for dep in &rustc_workspace[pkg].dependencies { + queue.push_back(dep.pkg); + } + for &tgt in rustc_workspace[pkg].targets.iter() { + if rustc_workspace[tgt].kind != TargetKind::Lib { + continue; } - 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_pkg_crates.keys().copied() { - 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 crates which opt in 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() { - let package = &cargo[pkg]; - if matches!( - (package.is_member, package.metadata.rustc_private), - (true, Some(false)) | (false, Some(false)) | (false, None) - ) { - continue; - } - for &from in pkg_crates.get(&pkg).into_iter().flatten() { - // Avoid creating duplicate dependencies - if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { - add_dep(&mut crate_graph, from, name.clone(), to); - } else { - eprintln!( - "Skipped {} for {:?}", - &name, &crate_graph[from].display_name + if let Some(file_id) = load(&rustc_workspace[tgt].root) { + let crate_id = add_target_crate_root( + &mut crate_graph, + &rustc_workspace[pkg], + rustc_build_data_map + .and_then(|it| it.get(&rustc_workspace[pkg].id)), + &cfg_options, + proc_macro_loader, + 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() { + add_dep(&mut crate_graph, crate_id, name.clone(), *krate); + } + 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_pkg_crates.keys().copied() { + 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 crates which opt in 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() { + let package = &cargo[pkg]; + if !package.metadata.rustc_private { + continue; + } + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + // Avoid creating duplicate dependencies + if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { + add_dep(&mut crate_graph, from, name.clone(), to); + } else { + eprintln!( + "Skipped {} for {:?}", + &name, &crate_graph[from].display_name + ); + } } } } } } - } else { - eprintln!("No cargo workspace"); } crate_graph } From 419b5a1bee3424b646991530f31b617a08c8375c Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 7 Mar 2021 12:59:15 +0000 Subject: [PATCH 06/12] Extract the large nested block into a function Also add some more detailed comments Extract into function deleted the previous comments --- crates/project_model/src/workspace.rs | 168 +++++++++++++++----------- 1 file changed, 97 insertions(+), 71 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index b969420cf3..b2ca7a4d25 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -376,6 +376,7 @@ fn cargo_to_crate_graph( cfg_options.insert_atom("debug_assertions".into()); let mut pkg_crates = FxHashMap::default(); + // Does any crate signal to rust-analyzer that they need the rustc_private crates? let mut has_private = false; // Next, create crates for each package, target pair for pkg in cargo.packages() { @@ -440,92 +441,117 @@ fn cargo_to_crate_graph( } } - let mut rustc_pkg_crates = FxHashMap::default(); - if has_private { // If the user provided a path to rustc sources, we add all the rustc_private crates // and create dependencies on them for the crates which opt-in to that if let Some(rustc_workspace) = rustc { - // rustc-dev crates start from 'rustc_driver' - // We want to collect all crates which are transitive dependencies of rustc_driver - if let Some(root_pkg) = rustc_workspace - .packages() - .find(|package| rustc_workspace[*package].name == "rustc_driver") - { - let mut queue = VecDeque::new(); - queue.push_back(root_pkg); - while let Some(pkg) = queue.pop_front() { - // Don't duplicate packages - if rustc_pkg_crates.contains_key(&pkg) { - continue; - } - for dep in &rustc_workspace[pkg].dependencies { - queue.push_back(dep.pkg); - } - for &tgt in rustc_workspace[pkg].targets.iter() { - if rustc_workspace[tgt].kind != TargetKind::Lib { - continue; - } - if let Some(file_id) = load(&rustc_workspace[tgt].root) { - let crate_id = add_target_crate_root( - &mut crate_graph, - &rustc_workspace[pkg], - rustc_build_data_map - .and_then(|it| it.get(&rustc_workspace[pkg].id)), - &cfg_options, - proc_macro_loader, - 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() { - add_dep(&mut crate_graph, crate_id, name.clone(), *krate); - } - rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); - } + handle_rustc_crates( + rustc_workspace, + load, + &mut crate_graph, + rustc_build_data_map, + &cfg_options, + proc_macro_loader, + &mut pkg_to_lib_crate, + &public_deps, + cargo, + &pkg_crates, + ); + } + } + crate_graph +} + +fn handle_rustc_crates( + rustc_workspace: &CargoWorkspace, + load: &mut dyn FnMut(&AbsPath) -> Option, + crate_graph: &mut CrateGraph, + rustc_build_data_map: Option<&FxHashMap>, + cfg_options: &CfgOptions, + proc_macro_loader: &dyn Fn(&Path) -> Vec, + pkg_to_lib_crate: &mut FxHashMap, CrateId>, + public_deps: &[(CrateName, CrateId)], + cargo: &CargoWorkspace, + pkg_crates: &FxHashMap, Vec>, +) { + let mut rustc_pkg_crates = FxHashMap::default(); + // The root package of the rustc-dev component is rustc_driver, so we match that + let root_pkg = + rustc_workspace.packages().find(|package| rustc_workspace[*package].name == "rustc_driver"); + // The rustc workspace might be incomplete (such as if rustc-dev is not installed for the current toolchain) + // and `rustcSource` is set to discover. + if let Some(root_pkg) = root_pkg { + // Iterate through every crate in the dependency subtree of rustc_driver using BFS + let mut queue = VecDeque::new(); + queue.push_back(root_pkg); + while let Some(pkg) = queue.pop_front() { + // Don't duplicate packages if they are dependended on a diamond pattern + // N.B. if this line is ommitted, we try and analyse either 48_000 or 480_000 crates + // neither of which makes + if rustc_pkg_crates.contains_key(&pkg) { + continue; + } + for dep in &rustc_workspace[pkg].dependencies { + queue.push_back(dep.pkg); + } + for &tgt in rustc_workspace[pkg].targets.iter() { + if rustc_workspace[tgt].kind != TargetKind::Lib { + continue; + } + if let Some(file_id) = load(&rustc_workspace[tgt].root) { + let crate_id = add_target_crate_root( + crate_graph, + &rustc_workspace[pkg], + rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), + &cfg_options, + proc_macro_loader, + file_id, + ); + 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); } + 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_pkg_crates.keys().copied() { - 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); - } - } + } + } + // Now add a dep edge from all targets of upstream to the lib + // target of downstream. + for pkg in rustc_pkg_crates.keys().copied() { + 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(crate_graph, from, name.clone(), to); } } + } + } + // Add a dependency on the rustc_private crates for all targets of each package + // which opts in + for dep in rustc_workspace.packages() { + let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); - // Add dependencies for all crates which opt in 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() { - let package = &cargo[pkg]; - if !package.metadata.rustc_private { - continue; - } - for &from in pkg_crates.get(&pkg).into_iter().flatten() { - // Avoid creating duplicate dependencies - if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { - add_dep(&mut crate_graph, from, name.clone(), to); - } else { - eprintln!( - "Skipped {} for {:?}", - &name, &crate_graph[from].display_name - ); - } - } + if let Some(&to) = pkg_to_lib_crate.get(&dep) { + for pkg in cargo.packages() { + let package = &cargo[pkg]; + if !package.metadata.rustc_private { + continue; + } + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + // Avoid creating duplicate dependencies + // This avoids the situation where `from` depends on e.g. `arrayvec`, but + // `rust_analyzer` thinks that it should use the one from the `rustcSource` + // instead of the one from `crates.io` + if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { + add_dep(crate_graph, from, name.clone(), to); } } } } } - crate_graph } fn add_target_crate_root( From 877f745551ff74da987a61f1c8a059d30140fb8a Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 7 Mar 2021 13:13:54 +0000 Subject: [PATCH 07/12] Fix the comment It's worse than I thought... --- 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 b2ca7a4d25..ea0c9ff606 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -478,16 +478,16 @@ fn handle_rustc_crates( // The root package of the rustc-dev component is rustc_driver, so we match that let root_pkg = rustc_workspace.packages().find(|package| rustc_workspace[*package].name == "rustc_driver"); - // The rustc workspace might be incomplete (such as if rustc-dev is not installed for the current toolchain) - // and `rustcSource` is set to discover. + // The rustc workspace might be incomplete (such as if rustc-dev is not + // installed for the current toolchain) and `rustcSource` is set to discover. if let Some(root_pkg) = root_pkg { // Iterate through every crate in the dependency subtree of rustc_driver using BFS let mut queue = VecDeque::new(); queue.push_back(root_pkg); while let Some(pkg) = queue.pop_front() { // Don't duplicate packages if they are dependended on a diamond pattern - // N.B. if this line is ommitted, we try and analyse either 48_000 or 480_000 crates - // neither of which makes + // N.B. if this line is ommitted, we try to analyse over 4_800_000 crates + // which is not ideal if rustc_pkg_crates.contains_key(&pkg) { continue; } From ddce6bb282764692d53b719bff4c37e3512d4556 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 09:05:19 +0000 Subject: [PATCH 08/12] Support disabling rustc build scripts --- crates/project_model/src/workspace.rs | 14 +++++++++++--- crates/rust-analyzer/src/cli/analysis_bench.rs | 3 +++ crates/rust-analyzer/src/cli/analysis_stats.rs | 3 +++ crates/rust-analyzer/src/cli/diagnostics.rs | 8 +++++++- crates/rust-analyzer/src/cli/load_cargo.rs | 10 +++++++--- crates/rust-analyzer/src/cli/ssr.rs | 18 ++++++++++++++---- crates/rust-analyzer/src/config.rs | 5 +++++ crates/rust-analyzer/src/reload.rs | 5 ++++- docs/user/generated_config.adoc | 2 ++ editors/code/package.json | 5 +++++ 10 files changed, 61 insertions(+), 12 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index ea0c9ff606..d754c8b55c 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -56,6 +56,7 @@ impl fmt::Debug for ProjectWorkspace { match self { ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => f .debug_struct("Cargo") + .field("root", &cargo.workspace_root()) .field("n_packages", &cargo.packages().len()) .field("n_sysroot_crates", &sysroot.crates().len()) .field( @@ -273,12 +274,19 @@ impl ProjectWorkspace { crate_graph } - pub fn collect_build_data_configs(&self, collector: &mut BuildDataCollector) { + pub fn collect_build_data_configs( + &self, + collector: &mut BuildDataCollector, + for_private: bool, + ) { match self { ProjectWorkspace::Cargo { cargo, rustc, .. } => { collector.add_config(&cargo.workspace_root(), cargo.build_data_config().clone()); - if let Some(rustc) = rustc { - collector.add_config(rustc.workspace_root(), rustc.build_data_config().clone()); + if for_private { + if let Some(rustc) = rustc { + collector + .add_config(rustc.workspace_root(), rustc.build_data_config().clone()); + } } } _ => {} diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 3bd7e678d3..104f2e8a20 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -68,6 +68,9 @@ impl BenchCmd { let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: self.load_output_dirs, with_proc_macro: self.with_proc_macro, + // This will currently never have rustcSource set, however if in + // future it does this will handle that case + run_rustc_build_scripts: true, }; let (mut host, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index ad0759bdad..5a84329608 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -63,6 +63,9 @@ impl AnalysisStatsCmd { let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: self.load_output_dirs, with_proc_macro: self.with_proc_macro, + // This will currently never have rustcSource set, however if in + // future it does this will handle that case + run_rustc_build_scripts: true, }; let (host, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs index 8b985716b0..e1966b5a79 100644 --- a/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/crates/rust-analyzer/src/cli/diagnostics.rs @@ -34,7 +34,13 @@ pub fn diagnostics( with_proc_macro: bool, ) -> Result<()> { let cargo_config = Default::default(); - let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check, with_proc_macro }; + let load_cargo_config = LoadCargoConfig { + load_out_dirs_from_check, + with_proc_macro, + // This will currently never have rustcSource set, however if in + // future it does this will handle that case + run_rustc_build_scripts: true, + }; let (host, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?; let db = host.raw_database(); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 310c36904e..3d7b5031a4 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -14,6 +14,7 @@ use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use crate::reload::{ProjectFolders, SourceRootConfig}; pub struct LoadCargoConfig { + pub run_rustc_build_scripts: bool, pub load_out_dirs_from_check: bool, pub with_proc_macro: bool, } @@ -53,7 +54,7 @@ pub fn load_workspace( let build_data = if config.load_out_dirs_from_check { let mut collector = BuildDataCollector::default(); - ws.collect_build_data_configs(&mut collector); + ws.collect_build_data_configs(&mut collector, config.run_rustc_build_scripts); Some(collector.collect(progress)?) } else { None @@ -136,8 +137,11 @@ mod tests { fn test_loading_rust_analyzer() -> Result<()> { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); let cargo_config = Default::default(); - let load_cargo_config = - LoadCargoConfig { load_out_dirs_from_check: false, with_proc_macro: false }; + let load_cargo_config = LoadCargoConfig { + load_out_dirs_from_check: false, + with_proc_macro: false, + run_rustc_build_scripts: false, + }; let (host, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs index 79f426fff1..8cc4eefc20 100644 --- a/crates/rust-analyzer/src/cli/ssr.rs +++ b/crates/rust-analyzer/src/cli/ssr.rs @@ -9,8 +9,13 @@ use ide_ssr::{MatchFinder, SsrPattern, SsrRule}; pub fn apply_ssr_rules(rules: Vec) -> Result<()> { use ide_db::base_db::SourceDatabaseExt; let cargo_config = Default::default(); - let load_cargo_config = - LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro: true }; + let load_cargo_config = LoadCargoConfig { + load_out_dirs_from_check: true, + with_proc_macro: true, + // This will currently never have rustcSource set, however if in + // future it does this will handle that case + run_rustc_build_scripts: true, + }; let (host, vfs, _proc_macro) = load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?; let db = host.raw_database(); @@ -36,8 +41,13 @@ pub fn search_for_patterns(patterns: Vec, debug_snippet: Option bool { self.data.cargo_runBuildScripts || self.data.procMacro_enable } + pub fn run_rustc_build_scripts(&self) -> bool { + self.run_build_scripts() && !self.data.cargo_disableRustcBuildScripts + } pub fn cargo(&self) -> CargoConfig { let rustc_source = self.data.rustcSource.as_ref().map(|rustc_src| { if rustc_src == "discover" { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index aa8504c3d5..da02be2dec 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -340,7 +340,10 @@ impl GlobalState { if self.config.run_build_scripts() && workspace_build_data.is_none() { let mut collector = BuildDataCollector::default(); for ws in &workspaces { - ws.collect_build_data_configs(&mut collector); + ws.collect_build_data_configs( + &mut collector, + self.config.run_rustc_build_scripts(), + ); } self.fetch_build_data_request(collector) } diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index 1dbf2a611d..602c9432e0 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -12,6 +12,8 @@ List of features to activate. [[rust-analyzer.cargo.runBuildScripts]]rust-analyzer.cargo.runBuildScripts (default: `false`):: Run build scripts (`build.rs`) for more precise code analysis. +[[rust-analyzer.cargo.disableRustcBuildScripts]]rust-analyzer.cargo.disableRustcBuildScripts (default: `false`):: + Disable running build scripts (`build.rs`) for the `rustc_private` crates in `rustcSource`. [[rust-analyzer.cargo.noDefaultFeatures]]rust-analyzer.cargo.noDefaultFeatures (default: `false`):: Do not activate the `default` feature. [[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`):: diff --git a/editors/code/package.json b/editors/code/package.json index 1987364bc0..82011bb445 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -413,6 +413,11 @@ "default": false, "type": "boolean" }, + "rust-analyzer.cargo.disableRustcBuildScripts": { + "markdownDescription": "Disable running build scripts (`build.rs`) for the `rustc_private` crates in `rustcSource`.", + "default": false, + "type": "boolean" + }, "rust-analyzer.cargo.noDefaultFeatures": { "markdownDescription": "Do not activate the `default` feature.", "default": false, From bbecea03fda57cced0b4ba95f4bbd45f8d88102c Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:37:52 +0000 Subject: [PATCH 09/12] Revert "Support disabling rustc build scripts" This reverts commit ddce6bb282764692d53b719bff4c37e3512d4556. --- crates/project_model/src/workspace.rs | 13 +++---------- crates/rust-analyzer/src/cli/analysis_bench.rs | 3 --- crates/rust-analyzer/src/cli/analysis_stats.rs | 3 --- crates/rust-analyzer/src/cli/diagnostics.rs | 8 +------- crates/rust-analyzer/src/cli/load_cargo.rs | 10 +++------- crates/rust-analyzer/src/cli/ssr.rs | 18 ++++-------------- crates/rust-analyzer/src/config.rs | 5 ----- crates/rust-analyzer/src/reload.rs | 5 +---- docs/user/generated_config.adoc | 2 -- editors/code/package.json | 5 ----- 10 files changed, 12 insertions(+), 60 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index d754c8b55c..aa7a8ee520 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -274,19 +274,12 @@ impl ProjectWorkspace { crate_graph } - pub fn collect_build_data_configs( - &self, - collector: &mut BuildDataCollector, - for_private: bool, - ) { + pub fn collect_build_data_configs(&self, collector: &mut BuildDataCollector) { match self { ProjectWorkspace::Cargo { cargo, rustc, .. } => { collector.add_config(&cargo.workspace_root(), cargo.build_data_config().clone()); - if for_private { - if let Some(rustc) = rustc { - collector - .add_config(rustc.workspace_root(), rustc.build_data_config().clone()); - } + if let Some(rustc) = rustc { + collector.add_config(rustc.workspace_root(), rustc.build_data_config().clone()); } } _ => {} diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 104f2e8a20..3bd7e678d3 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -68,9 +68,6 @@ impl BenchCmd { let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: self.load_output_dirs, with_proc_macro: self.with_proc_macro, - // This will currently never have rustcSource set, however if in - // future it does this will handle that case - run_rustc_build_scripts: true, }; let (mut host, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 5a84329608..ad0759bdad 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -63,9 +63,6 @@ impl AnalysisStatsCmd { let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: self.load_output_dirs, with_proc_macro: self.with_proc_macro, - // This will currently never have rustcSource set, however if in - // future it does this will handle that case - run_rustc_build_scripts: true, }; let (host, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs index e1966b5a79..8b985716b0 100644 --- a/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/crates/rust-analyzer/src/cli/diagnostics.rs @@ -34,13 +34,7 @@ pub fn diagnostics( with_proc_macro: bool, ) -> Result<()> { let cargo_config = Default::default(); - let load_cargo_config = LoadCargoConfig { - load_out_dirs_from_check, - with_proc_macro, - // This will currently never have rustcSource set, however if in - // future it does this will handle that case - run_rustc_build_scripts: true, - }; + let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check, with_proc_macro }; let (host, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?; let db = host.raw_database(); diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 3d7b5031a4..310c36904e 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -14,7 +14,6 @@ use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use crate::reload::{ProjectFolders, SourceRootConfig}; pub struct LoadCargoConfig { - pub run_rustc_build_scripts: bool, pub load_out_dirs_from_check: bool, pub with_proc_macro: bool, } @@ -54,7 +53,7 @@ pub fn load_workspace( let build_data = if config.load_out_dirs_from_check { let mut collector = BuildDataCollector::default(); - ws.collect_build_data_configs(&mut collector, config.run_rustc_build_scripts); + ws.collect_build_data_configs(&mut collector); Some(collector.collect(progress)?) } else { None @@ -137,11 +136,8 @@ mod tests { fn test_loading_rust_analyzer() -> Result<()> { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); let cargo_config = Default::default(); - let load_cargo_config = LoadCargoConfig { - load_out_dirs_from_check: false, - with_proc_macro: false, - run_rustc_build_scripts: false, - }; + let load_cargo_config = + LoadCargoConfig { load_out_dirs_from_check: false, with_proc_macro: false }; let (host, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs index 8cc4eefc20..79f426fff1 100644 --- a/crates/rust-analyzer/src/cli/ssr.rs +++ b/crates/rust-analyzer/src/cli/ssr.rs @@ -9,13 +9,8 @@ use ide_ssr::{MatchFinder, SsrPattern, SsrRule}; pub fn apply_ssr_rules(rules: Vec) -> Result<()> { use ide_db::base_db::SourceDatabaseExt; let cargo_config = Default::default(); - let load_cargo_config = LoadCargoConfig { - load_out_dirs_from_check: true, - with_proc_macro: true, - // This will currently never have rustcSource set, however if in - // future it does this will handle that case - run_rustc_build_scripts: true, - }; + let load_cargo_config = + LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro: true }; let (host, vfs, _proc_macro) = load_workspace_at(&std::env::current_dir()?, &cargo_config, &load_cargo_config, &|_| {})?; let db = host.raw_database(); @@ -41,13 +36,8 @@ pub fn search_for_patterns(patterns: Vec, debug_snippet: Option bool { self.data.cargo_runBuildScripts || self.data.procMacro_enable } - pub fn run_rustc_build_scripts(&self) -> bool { - self.run_build_scripts() && !self.data.cargo_disableRustcBuildScripts - } pub fn cargo(&self) -> CargoConfig { let rustc_source = self.data.rustcSource.as_ref().map(|rustc_src| { if rustc_src == "discover" { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index da02be2dec..aa8504c3d5 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -340,10 +340,7 @@ impl GlobalState { if self.config.run_build_scripts() && workspace_build_data.is_none() { let mut collector = BuildDataCollector::default(); for ws in &workspaces { - ws.collect_build_data_configs( - &mut collector, - self.config.run_rustc_build_scripts(), - ); + ws.collect_build_data_configs(&mut collector); } self.fetch_build_data_request(collector) } diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index 602c9432e0..1dbf2a611d 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -12,8 +12,6 @@ List of features to activate. [[rust-analyzer.cargo.runBuildScripts]]rust-analyzer.cargo.runBuildScripts (default: `false`):: Run build scripts (`build.rs`) for more precise code analysis. -[[rust-analyzer.cargo.disableRustcBuildScripts]]rust-analyzer.cargo.disableRustcBuildScripts (default: `false`):: - Disable running build scripts (`build.rs`) for the `rustc_private` crates in `rustcSource`. [[rust-analyzer.cargo.noDefaultFeatures]]rust-analyzer.cargo.noDefaultFeatures (default: `false`):: Do not activate the `default` feature. [[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`):: diff --git a/editors/code/package.json b/editors/code/package.json index 82011bb445..1987364bc0 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -413,11 +413,6 @@ "default": false, "type": "boolean" }, - "rust-analyzer.cargo.disableRustcBuildScripts": { - "markdownDescription": "Disable running build scripts (`build.rs`) for the `rustc_private` crates in `rustcSource`.", - "default": false, - "type": "boolean" - }, "rust-analyzer.cargo.noDefaultFeatures": { "markdownDescription": "Do not activate the `default` feature.", "default": false, From d5d406fa780a18d350fc925f0753c0ec5eaa4a62 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:41:40 +0000 Subject: [PATCH 10/12] Only show directory name --- crates/project_model/src/workspace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index aa7a8ee520..6001d694f9 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -56,7 +56,7 @@ impl fmt::Debug for ProjectWorkspace { match self { ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg } => f .debug_struct("Cargo") - .field("root", &cargo.workspace_root()) + .field("root", &cargo.workspace_root().file_name()) .field("n_packages", &cargo.packages().len()) .field("n_sysroot_crates", &sysroot.crates().len()) .field( From d0a51d710edf5893d1f8ffe58647fd4aa795096c Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:42:18 +0000 Subject: [PATCH 11/12] Never run cargo check on the rustc source --- crates/project_model/src/workspace.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 6001d694f9..1b53fcc30a 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -276,11 +276,8 @@ impl ProjectWorkspace { pub fn collect_build_data_configs(&self, collector: &mut BuildDataCollector) { match self { - ProjectWorkspace::Cargo { cargo, rustc, .. } => { + ProjectWorkspace::Cargo { cargo, .. } => { collector.add_config(&cargo.workspace_root(), cargo.build_data_config().clone()); - if let Some(rustc) = rustc { - collector.add_config(rustc.workspace_root(), rustc.build_data_config().clone()); - } } _ => {} } From 20007fd3a8aa16bec0c4f9ebc1489c157f846df4 Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Mon, 8 Mar 2021 16:47:40 +0000 Subject: [PATCH 12/12] Document rustc_private in metadata --- crates/rust-analyzer/src/config.rs | 3 ++- docs/user/generated_config.adoc | 2 +- editors/code/package.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3671367025..4417c8d13d 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -180,7 +180,8 @@ config_data! { runnables_cargoExtraArgs: Vec = "[]", /// Path to the rust compiler sources, for usage in rustc_private projects, or "discover" - /// to try to automatically find it. + /// to try to automatically find it. Any project which uses rust-analyzer with the rustcPrivate + /// crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. rustcSource : Option = "null", /// Additional arguments to `rustfmt`. diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index 1dbf2a611d..504133070b 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -105,7 +105,7 @@ [[rust-analyzer.runnables.cargoExtraArgs]]rust-analyzer.runnables.cargoExtraArgs (default: `[]`):: Additional arguments to be passed to cargo for runnables such as tests or binaries.\nFor example, it may be `--release`. [[rust-analyzer.rustcSource]]rust-analyzer.rustcSource (default: `null`):: - Path to the rust compiler sources, for usage in rustc_private projects, or "discover" to try to automatically find it. + Path to the rust compiler sources, for usage in rustc_private projects, or "discover" to try to automatically find it. Any project which uses rust-analyzer with the rustcPrivate crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. [[rust-analyzer.rustfmt.extraArgs]]rust-analyzer.rustfmt.extraArgs (default: `[]`):: Additional arguments to `rustfmt`. [[rust-analyzer.rustfmt.overrideCommand]]rust-analyzer.rustfmt.overrideCommand (default: `null`):: diff --git a/editors/code/package.json b/editors/code/package.json index 1987364bc0..b39e8fbe39 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -707,7 +707,7 @@ } }, "rust-analyzer.rustcSource": { - "markdownDescription": "Path to the rust compiler sources, for usage in rustc_private projects, or \"discover\" to try to automatically find it.", + "markdownDescription": "Path to the rust compiler sources, for usage in rustc_private projects, or \"discover\" to try to automatically find it. Any project which uses rust-analyzer with the rustcPrivate crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.", "default": null, "type": [ "null",