Skip to content

Commit aff6cb0

Browse files
committed
Auto merge of #14282 - Veykril:rustc_private-proc-macro, r=Veykril
fix: Load proc-macros for rustc_private crates Fixes #13591 Verified that this makes things work in the clippy repo (like resolving `sym` things for example)
2 parents a9d97b6 + c978648 commit aff6cb0

File tree

3 files changed

+98
-22
lines changed

3 files changed

+98
-22
lines changed

crates/project-model/src/build_scripts.rs

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ use std::{
1515

1616
use cargo_metadata::{camino::Utf8Path, Message};
1717
use la_arena::ArenaMap;
18-
use paths::AbsPathBuf;
18+
use paths::{AbsPath, AbsPathBuf};
1919
use rustc_hash::FxHashMap;
2020
use semver::Version;
2121
use serde::Deserialize;
2222

2323
use crate::{
24-
cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
24+
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
2525
InvocationStrategy, Package,
2626
};
2727

@@ -250,7 +250,7 @@ impl WorkspaceBuildScripts {
250250

251251
if tracing::enabled!(tracing::Level::INFO) {
252252
for package in workspace.packages() {
253-
let package_build_data = &mut outputs[package];
253+
let package_build_data = &outputs[package];
254254
if !package_build_data.is_unchanged() {
255255
tracing::info!(
256256
"{}: {:?}",
@@ -378,6 +378,80 @@ impl WorkspaceBuildScripts {
378378
pub(crate) fn get_output(&self, idx: Package) -> Option<&BuildScriptOutput> {
379379
self.outputs.get(idx)
380380
}
381+
382+
pub(crate) fn rustc_crates(
383+
rustc: &CargoWorkspace,
384+
current_dir: &AbsPath,
385+
extra_env: &FxHashMap<String, String>,
386+
) -> Self {
387+
let mut bs = WorkspaceBuildScripts::default();
388+
for p in rustc.packages() {
389+
bs.outputs.insert(p, BuildScriptOutput::default());
390+
}
391+
let res = (|| {
392+
let target_libdir = (|| {
393+
let mut cargo_config = Command::new(toolchain::cargo());
394+
cargo_config.envs(extra_env);
395+
cargo_config
396+
.current_dir(current_dir)
397+
.args(["rustc", "-Z", "unstable-options", "--print", "target-libdir"])
398+
.env("RUSTC_BOOTSTRAP", "1");
399+
if let Ok(it) = utf8_stdout(cargo_config) {
400+
return Ok(it);
401+
}
402+
let mut cmd = Command::new(toolchain::rustc());
403+
cmd.envs(extra_env);
404+
cmd.args(["--print", "target-libdir"]);
405+
utf8_stdout(cmd)
406+
})()?;
407+
408+
let target_libdir = AbsPathBuf::try_from(PathBuf::from(target_libdir))
409+
.map_err(|_| anyhow::format_err!("target-libdir was not an absolute path"))?;
410+
tracing::info!("Loading rustc proc-macro paths from {}", target_libdir.display());
411+
412+
let proc_macro_dylibs: Vec<(String, AbsPathBuf)> = std::fs::read_dir(target_libdir)?
413+
.filter_map(|entry| {
414+
let dir_entry = entry.ok()?;
415+
if dir_entry.file_type().ok()?.is_file() {
416+
let path = dir_entry.path();
417+
tracing::info!("p{:?}", path);
418+
let extension = path.extension()?;
419+
if extension == "dll" || extension == "so" {
420+
let name = path.file_stem()?.to_str()?.split_once('-')?.0.to_owned();
421+
let path = AbsPathBuf::try_from(path).ok()?;
422+
return Some((name, path));
423+
}
424+
}
425+
None
426+
})
427+
.collect();
428+
for p in rustc.packages() {
429+
if let Some((_, path)) =
430+
proc_macro_dylibs.iter().find(|(name, _)| *name == rustc[p].name)
431+
{
432+
bs.outputs[p].proc_macro_dylib_path = Some(path.clone());
433+
}
434+
}
435+
436+
if tracing::enabled!(tracing::Level::INFO) {
437+
for package in rustc.packages() {
438+
let package_build_data = &bs.outputs[package];
439+
if !package_build_data.is_unchanged() {
440+
tracing::info!(
441+
"{}: {:?}",
442+
rustc[package].manifest.parent().display(),
443+
package_build_data,
444+
);
445+
}
446+
}
447+
}
448+
Ok(())
449+
})();
450+
if let Err::<_, anyhow::Error>(e) = res {
451+
bs.error = Some(e.to_string());
452+
}
453+
bs
454+
}
381455
}
382456

383457
// FIXME: Find a better way to know if it is a dylib.

crates/project-model/src/sysroot.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,17 @@ impl Sysroot {
8888
}
8989

9090
pub fn discover_with_src_override(
91-
dir: &AbsPath,
91+
current_dir: &AbsPath,
9292
extra_env: &FxHashMap<String, String>,
9393
src: AbsPathBuf,
9494
) -> Result<Sysroot> {
95-
tracing::debug!("discovering sysroot for {}", dir.display());
96-
let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
95+
tracing::debug!("discovering sysroot for {}", current_dir.display());
96+
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?;
9797
Ok(Sysroot::load(sysroot_dir, src))
9898
}
9999

100-
pub fn discover_rustc(
101-
cargo_toml: &ManifestPath,
102-
extra_env: &FxHashMap<String, String>,
103-
) -> Option<ManifestPath> {
104-
tracing::debug!("discovering rustc source for {}", cargo_toml.display());
105-
let current_dir = cargo_toml.parent();
106-
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env).ok()?;
107-
get_rustc_src(&sysroot_dir)
100+
pub fn discover_rustc(&self) -> Option<ManifestPath> {
101+
get_rustc_src(&self.root)
108102
}
109103

110104
pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf) -> Result<Sysroot> {

crates/project-model/src/workspace.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub enum ProjectWorkspace {
7070
cargo: CargoWorkspace,
7171
build_scripts: WorkspaceBuildScripts,
7272
sysroot: Option<Sysroot>,
73-
rustc: Option<CargoWorkspace>,
73+
rustc: Option<(CargoWorkspace, WorkspaceBuildScripts)>,
7474
/// Holds cfg flags for the current target. We get those by running
7575
/// `rustc --print cfg`.
7676
///
@@ -116,7 +116,7 @@ impl fmt::Debug for ProjectWorkspace {
116116
.field("sysroot", &sysroot.is_some())
117117
.field(
118118
"n_rustc_compiler_crates",
119-
&rustc.as_ref().map_or(0, |rc| rc.packages().len()),
119+
&rustc.as_ref().map_or(0, |(rc, _)| rc.packages().len()),
120120
)
121121
.field("n_rustc_cfg", &rustc_cfg.len())
122122
.field("n_cfg_overrides", &cfg_overrides.len())
@@ -243,7 +243,7 @@ impl ProjectWorkspace {
243243
let rustc_dir = match &config.rustc_source {
244244
Some(RustcSource::Path(path)) => ManifestPath::try_from(path.clone()).ok(),
245245
Some(RustcSource::Discover) => {
246-
Sysroot::discover_rustc(&cargo_toml, &config.extra_env)
246+
sysroot.as_ref().and_then(Sysroot::discover_rustc)
247247
}
248248
None => None,
249249
};
@@ -257,7 +257,15 @@ impl ProjectWorkspace {
257257
config,
258258
progress,
259259
) {
260-
Ok(meta) => Some(CargoWorkspace::new(meta)),
260+
Ok(meta) => {
261+
let workspace = CargoWorkspace::new(meta);
262+
let buildscripts = WorkspaceBuildScripts::rustc_crates(
263+
&workspace,
264+
cargo_toml.parent(),
265+
&config.extra_env,
266+
);
267+
Some((workspace, buildscripts))
268+
}
261269
Err(e) => {
262270
tracing::error!(
263271
%e,
@@ -531,7 +539,7 @@ impl ProjectWorkspace {
531539
PackageRoot { is_local, include, exclude }
532540
})
533541
.chain(mk_sysroot(sysroot.as_ref(), Some(cargo.workspace_root())))
534-
.chain(rustc.iter().flat_map(|rustc| {
542+
.chain(rustc.iter().flat_map(|(rustc, _)| {
535543
rustc.packages().map(move |krate| PackageRoot {
536544
is_local: false,
537545
include: vec![rustc[krate].manifest.parent().to_path_buf()],
@@ -559,7 +567,7 @@ impl ProjectWorkspace {
559567
sysroot_package_len + project.n_crates()
560568
}
561569
ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => {
562-
let rustc_package_len = rustc.as_ref().map_or(0, |it| it.packages().len());
570+
let rustc_package_len = rustc.as_ref().map_or(0, |(it, _)| it.packages().len());
563571
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
564572
cargo.packages().len() + sysroot_package_len + rustc_package_len
565573
}
@@ -778,7 +786,7 @@ fn project_json_to_crate_graph(
778786
fn cargo_to_crate_graph(
779787
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
780788
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
781-
rustc: &Option<CargoWorkspace>,
789+
rustc: &Option<(CargoWorkspace, WorkspaceBuildScripts)>,
782790
cargo: &CargoWorkspace,
783791
sysroot: Option<&Sysroot>,
784792
rustc_cfg: Vec<CfgFlag>,
@@ -924,7 +932,7 @@ fn cargo_to_crate_graph(
924932
if has_private {
925933
// If the user provided a path to rustc sources, we add all the rustc_private crates
926934
// and create dependencies on them for the crates which opt-in to that
927-
if let Some(rustc_workspace) = rustc {
935+
if let Some((rustc_workspace, build_scripts)) = rustc {
928936
handle_rustc_crates(
929937
&mut crate_graph,
930938
&mut pkg_to_lib_crate,

0 commit comments

Comments
 (0)