Require opt in to rustc_private

This gives the advantage that

A future extension would be to check for `feature(rustc_private)` instead
This commit is contained in:
Daniel McNab 2021-03-07 12:24:20 +00:00
parent 71a254c1a1
commit 9246df669a
2 changed files with 76 additions and 76 deletions

View file

@ -112,7 +112,7 @@ pub struct PackageData {
#[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)] #[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)]
pub struct RustAnalyzerPackageMetaData { pub struct RustAnalyzerPackageMetaData {
pub rustc_private: Option<bool>, pub rustc_private: bool,
} }
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]

View file

@ -376,9 +376,10 @@ fn cargo_to_crate_graph(
cfg_options.insert_atom("debug_assertions".into()); cfg_options.insert_atom("debug_assertions".into());
let mut pkg_crates = FxHashMap::default(); let mut pkg_crates = FxHashMap::default();
let mut has_private = false;
// Next, create crates for each package, target pair // Next, create crates for each package, target pair
for pkg in cargo.packages() { for pkg in cargo.packages() {
has_private |= cargo[pkg].metadata.rustc_private;
let mut lib_tgt = None; let mut lib_tgt = None;
for &tgt in cargo[pkg].targets.iter() { for &tgt in cargo[pkg].targets.iter() {
if let Some(file_id) = load(&cargo[tgt].root) { 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(); let mut rustc_pkg_crates = FxHashMap::default();
// If the user provided a path to rustc sources, we add all the rustc_private crates if has_private {
// and create dependencies on them for the crates which opt-in to that // If the user provided a path to rustc sources, we add all the rustc_private crates
if let Some(rustc_workspace) = rustc { // and create dependencies on them for the crates which opt-in to that
// rustc-dev crates start from 'rustc_driver' if let Some(rustc_workspace) = rustc {
// Therefore, we collect all crates which are transitive dependencies of rustc_driver // rustc-dev crates start from 'rustc_driver'
if let Some(root_pkg) = rustc_workspace // We want to collect all crates which are transitive dependencies of rustc_driver
.packages() if let Some(root_pkg) = rustc_workspace
.find(|package| rustc_workspace[*package].name == "rustc_driver") .packages()
{ .find(|package| rustc_workspace[*package].name == "rustc_driver")
let mut queue = VecDeque::new(); {
queue.push_back(root_pkg); let mut queue = VecDeque::new();
while let Some(pkg) = queue.pop_front() { queue.push_back(root_pkg);
if rustc_pkg_crates.contains_key(&pkg) { while let Some(pkg) = queue.pop_front() {
continue; // Don't duplicate packages
} if rustc_pkg_crates.contains_key(&pkg) {
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; continue;
} }
if let Some(file_id) = load(&rustc_workspace[tgt].root) { for dep in &rustc_workspace[pkg].dependencies {
let crate_id = add_target_crate_root( queue.push_back(dep.pkg);
&mut crate_graph, }
&rustc_workspace[pkg], for &tgt in rustc_workspace[pkg].targets.iter() {
rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), if rustc_workspace[tgt].kind != TargetKind::Lib {
&cfg_options, continue;
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); 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
// Now add a dep edge from all targets of upstream to the lib .and_then(|it| it.get(&rustc_workspace[pkg].id)),
// target of downstream. &cfg_options,
for pkg in rustc_pkg_crates.keys().copied() { proc_macro_loader,
for dep in rustc_workspace[pkg].dependencies.iter() { file_id,
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
); );
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 crate_graph
} }