Merge commit 'ac998a74b3' into sync-from-ra

This commit is contained in:
Laurențiu Nicola 2024-02-18 09:41:20 +02:00
parent d33d8675d0
commit 6b17dba68c
178 changed files with 7101 additions and 1965 deletions

View file

@ -20,10 +20,11 @@ use paths::{AbsPath, AbsPathBuf};
use rustc_hash::{FxHashMap, FxHashSet};
use semver::Version;
use serde::Deserialize;
use toolchain::Tool;
use crate::{
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
InvocationStrategy, Package,
InvocationStrategy, Package, Sysroot, TargetKind,
};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
@ -61,6 +62,7 @@ impl WorkspaceBuildScripts {
config: &CargoConfig,
allowed_features: &FxHashSet<String>,
workspace_root: &AbsPathBuf,
sysroot: Option<&Sysroot>,
) -> io::Result<Command> {
let mut cmd = match config.run_build_script_command.as_deref() {
Some([program, args @ ..]) => {
@ -69,7 +71,8 @@ impl WorkspaceBuildScripts {
cmd
}
_ => {
let mut cmd = Command::new(toolchain::cargo());
let mut cmd = Command::new(Tool::Cargo.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
cmd.args(&config.extra_args);
@ -133,6 +136,7 @@ impl WorkspaceBuildScripts {
workspace: &CargoWorkspace,
progress: &dyn Fn(String),
toolchain: &Option<Version>,
sysroot: Option<&Sysroot>,
) -> io::Result<WorkspaceBuildScripts> {
const RUST_1_62: Version = Version::new(1, 62, 0);
@ -151,6 +155,7 @@ impl WorkspaceBuildScripts {
config,
&allowed_features,
&workspace.workspace_root().to_path_buf(),
sysroot,
)?,
workspace,
current_dir,
@ -165,6 +170,7 @@ impl WorkspaceBuildScripts {
config,
&allowed_features,
&workspace.workspace_root().to_path_buf(),
sysroot,
)?;
cmd.args(["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
@ -194,7 +200,7 @@ impl WorkspaceBuildScripts {
))
}
};
let cmd = Self::build_command(config, &Default::default(), workspace_root)?;
let cmd = Self::build_command(config, &Default::default(), workspace_root, None)?;
// NB: Cargo.toml could have been modified between `cargo metadata` and
// `cargo check`. We shouldn't assume that package ids we see here are
// exactly those from `config`.
@ -415,6 +421,7 @@ impl WorkspaceBuildScripts {
rustc: &CargoWorkspace,
current_dir: &AbsPath,
extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>,
) -> Self {
let mut bs = WorkspaceBuildScripts::default();
for p in rustc.packages() {
@ -422,7 +429,8 @@ impl WorkspaceBuildScripts {
}
let res = (|| {
let target_libdir = (|| {
let mut cargo_config = Command::new(toolchain::cargo());
let mut cargo_config = Command::new(Tool::Cargo.path());
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
cargo_config.envs(extra_env);
cargo_config
.current_dir(current_dir)
@ -431,7 +439,8 @@ impl WorkspaceBuildScripts {
if let Ok(it) = utf8_stdout(cargo_config) {
return Ok(it);
}
let mut cmd = Command::new(toolchain::rustc());
let mut cmd = Command::new(Tool::Rustc.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env);
cmd.args(["--print", "target-libdir"]);
utf8_stdout(cmd)
@ -458,7 +467,11 @@ impl WorkspaceBuildScripts {
.collect();
for p in rustc.packages() {
let package = &rustc[p];
if package.targets.iter().any(|&it| rustc[it].is_proc_macro) {
if package
.targets
.iter()
.any(|&it| matches!(rustc[it].kind, TargetKind::Lib { is_proc_macro: true }))
{
if let Some((_, path)) = proc_macro_dylibs
.iter()
.find(|(name, _)| *name.trim_start_matches("lib") == package.name)

View file

@ -12,8 +12,9 @@ use paths::{AbsPath, AbsPathBuf};
use rustc_hash::{FxHashMap, FxHashSet};
use serde::Deserialize;
use serde_json::from_value;
use toolchain::Tool;
use crate::{utf8_stdout, InvocationLocation, ManifestPath};
use crate::{utf8_stdout, InvocationLocation, ManifestPath, Sysroot};
use crate::{CfgOverrides, InvocationStrategy};
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
@ -188,8 +189,6 @@ pub struct TargetData {
pub root: AbsPathBuf,
/// Kind of target
pub kind: TargetKind,
/// Is this target a proc-macro
pub is_proc_macro: bool,
/// Required features of the target without which it won't build
pub required_features: Vec<String>,
}
@ -198,7 +197,10 @@ pub struct TargetData {
pub enum TargetKind {
Bin,
/// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
Lib,
Lib {
/// Is this target a proc-macro
is_proc_macro: bool,
},
Example,
Test,
Bench,
@ -215,8 +217,8 @@ impl TargetKind {
"bench" => TargetKind::Bench,
"example" => TargetKind::Example,
"custom-build" => TargetKind::BuildScript,
"proc-macro" => TargetKind::Lib,
_ if kind.contains("lib") => TargetKind::Lib,
"proc-macro" => TargetKind::Lib { is_proc_macro: true },
_ if kind.contains("lib") => TargetKind::Lib { is_proc_macro: false },
_ => continue,
};
}
@ -236,12 +238,13 @@ impl CargoWorkspace {
cargo_toml: &ManifestPath,
current_dir: &AbsPath,
config: &CargoConfig,
sysroot: Option<&Sysroot>,
progress: &dyn Fn(String),
) -> anyhow::Result<cargo_metadata::Metadata> {
let targets = find_list_of_build_targets(config, cargo_toml);
let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
let mut meta = MetadataCommand::new();
meta.cargo_path(toolchain::cargo());
meta.cargo_path(Tool::Cargo.path());
meta.manifest_path(cargo_toml.to_path_buf());
match &config.features {
CargoFeatures::All => {
@ -289,6 +292,7 @@ impl CargoWorkspace {
(|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
let mut command = meta.cargo_command();
Sysroot::set_rustup_toolchain_env(&mut command, sysroot);
command.envs(&config.extra_env);
let output = command.output()?;
if !output.status.success() {
@ -368,7 +372,6 @@ impl CargoWorkspace {
name,
root: AbsPathBuf::assert(src_path.into()),
kind: TargetKind::new(&kind),
is_proc_macro: *kind == ["proc-macro"],
required_features,
});
pkg_data.targets.push(tgt);
@ -476,24 +479,30 @@ impl CargoWorkspace {
}
}
fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
fn find_list_of_build_targets(
config: &CargoConfig,
cargo_toml: &ManifestPath,
sysroot: Option<&Sysroot>,
) -> Vec<String> {
if let Some(target) = &config.target {
return [target.into()].to_vec();
}
let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env, sysroot);
if !build_targets.is_empty() {
return build_targets;
}
rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
rustc_discover_host_triple(cargo_toml, &config.extra_env, sysroot).into_iter().collect()
}
fn rustc_discover_host_triple(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>,
) -> Option<String> {
let mut rustc = Command::new(toolchain::rustc());
let mut rustc = Command::new(Tool::Rustc.path());
Sysroot::set_rustup_toolchain_env(&mut rustc, sysroot);
rustc.envs(extra_env);
rustc.current_dir(cargo_toml.parent()).arg("-vV");
tracing::debug!("Discovering host platform by {:?}", rustc);
@ -519,8 +528,10 @@ fn rustc_discover_host_triple(
fn cargo_config_build_target(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
sysroot: Option<&Sysroot>,
) -> Vec<String> {
let mut cargo_config = Command::new(toolchain::cargo());
let mut cargo_config = Command::new(Tool::Cargo.path());
Sysroot::set_rustup_toolchain_env(&mut cargo_config, sysroot);
cargo_config.envs(extra_env);
cargo_config
.current_dir(cargo_toml.parent())

View file

@ -49,7 +49,7 @@
//! user explores them belongs to that extension (it's totally valid to change
//! rust-project.json over time via configuration request!)
use base_db::{CrateDisplayName, CrateId, CrateName, Dependency, DependencyKind, Edition};
use base_db::{CrateDisplayName, CrateId, CrateName, Dependency, Edition};
use la_arena::RawIdx;
use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap;
@ -135,7 +135,6 @@ impl ProjectJson {
Dependency::new(
dep_data.name,
CrateId::from_raw(RawIdx::from(dep_data.krate as u32)),
DependencyKind::Normal,
)
})
.collect::<Vec<_>>(),

View file

@ -8,17 +8,13 @@ use rustc_hash::FxHashMap;
use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
/// Determines how `rustc --print cfg` is discovered and invoked.
///
/// There options are supported:
/// - [`RustcCfgConfig::Cargo`], which relies on `cargo rustc --print cfg`
/// and `RUSTC_BOOTSTRAP`.
/// - [`RustcCfgConfig::Explicit`], which uses an explicit path to the `rustc`
/// binary in the sysroot.
/// - [`RustcCfgConfig::Discover`], which uses [`toolchain::rustc`].
pub(crate) enum RustcCfgConfig<'a> {
Cargo(&'a ManifestPath),
Explicit(&'a Sysroot),
Discover,
/// Use `rustc --print cfg`, either from with the binary from the sysroot or by discovering via
/// [`toolchain::rustc`].
Rustc(Option<&'a Sysroot>),
/// Use `cargo --print cfg`, either from with the binary from the sysroot or by discovering via
/// [`toolchain::cargo`].
Cargo(Option<&'a Sysroot>, &'a ManifestPath),
}
pub(crate) fn get(
@ -71,9 +67,10 @@ fn get_rust_cfgs(
extra_env: &FxHashMap<String, String>,
config: RustcCfgConfig<'_>,
) -> anyhow::Result<String> {
let mut cmd = match config {
RustcCfgConfig::Cargo(cargo_toml) => {
let mut cmd = Command::new(toolchain::cargo());
let sysroot = match config {
RustcCfgConfig::Cargo(sysroot, cargo_toml) => {
let mut cmd = Command::new(toolchain::Tool::Cargo.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env);
cmd.current_dir(cargo_toml.parent())
.args(["rustc", "-Z", "unstable-options", "--print", "cfg"])
@ -82,25 +79,24 @@ fn get_rust_cfgs(
cmd.args(["--target", target]);
}
return utf8_stdout(cmd).context("Unable to run `cargo rustc`");
}
RustcCfgConfig::Explicit(sysroot) => {
let rustc: std::path::PathBuf = sysroot.discover_rustc()?.into();
tracing::debug!(?rustc, "using explicit rustc from sysroot");
Command::new(rustc)
}
RustcCfgConfig::Discover => {
let rustc = toolchain::rustc();
tracing::debug!(?rustc, "using rustc from env");
Command::new(rustc)
match utf8_stdout(cmd) {
Ok(it) => return Ok(it),
Err(e) => {
tracing::warn!("failed to run `cargo rustc --print cfg`, falling back to invoking rustc directly: {e}");
sysroot
}
}
}
RustcCfgConfig::Rustc(sysroot) => sysroot,
};
let mut cmd = Command::new(toolchain::Tool::Rustc.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env);
cmd.args(["--print", "cfg", "-O"]);
if let Some(target) = target {
cmd.args(["--target", target]);
}
utf8_stdout(cmd).context("Unable to run `rustc`")
utf8_stdout(cmd).context("unable to fetch cfgs via `rustc --print cfg -O`")
}

View file

@ -4,24 +4,38 @@
//! 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::{env, fs, iter, ops, path::PathBuf, process::Command};
use std::{env, fs, iter, ops, path::PathBuf, process::Command, sync::Arc};
use anyhow::{format_err, Context, Result};
use anyhow::{format_err, Result};
use base_db::CrateName;
use itertools::Itertools;
use la_arena::{Arena, Idx};
use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap;
use toolchain::probe_for_binary;
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath};
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone)]
pub struct Sysroot {
root: AbsPathBuf,
src_root: AbsPathBuf,
src_root: Option<Result<AbsPathBuf, Arc<anyhow::Error>>>,
mode: SysrootMode,
}
impl Eq for Sysroot {}
impl PartialEq for Sysroot {
fn eq(&self, other: &Self) -> bool {
self.root == other.root
&& self.mode == other.mode
&& match (&self.src_root, &other.src_root) {
(Some(Ok(this)), Some(Ok(other))) => this == other,
(None, None) | (Some(Err(_)), Some(Err(_))) => true,
_ => false,
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum SysrootMode {
Workspace(CargoWorkspace),
@ -86,8 +100,8 @@ impl Sysroot {
/// Returns the sysroot "source" directory, where stdlib sources are located, like:
/// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library`
pub fn src_root(&self) -> &AbsPath {
&self.src_root
pub fn src_root(&self) -> Option<&AbsPath> {
self.src_root.as_ref()?.as_deref().ok()
}
pub fn is_empty(&self) -> bool {
@ -98,6 +112,11 @@ impl Sysroot {
}
pub fn loading_warning(&self) -> Option<String> {
let src_root = match &self.src_root {
None => return Some(format!("sysroot at `{}` has no library sources", self.root)),
Some(Ok(src_root)) => src_root,
Some(Err(e)) => return Some(e.to_string()),
};
let has_core = match &self.mode {
SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"),
SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(),
@ -108,10 +127,7 @@ impl Sysroot {
} else {
" try running `rustup component add rust-src` to possible fix this"
};
Some(format!(
"could not find libcore in loaded sysroot at `{}`{var_note}",
self.src_root.as_path(),
))
Some(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,))
} else {
None
}
@ -140,8 +156,19 @@ impl Sysroot {
tracing::debug!("discovering sysroot for {dir}");
let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
let sysroot_src_dir =
discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env)?;
Ok(Sysroot::load(sysroot_dir, sysroot_src_dir, metadata))
discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env);
Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata))
}
pub fn discover_no_source(
dir: &AbsPath,
extra_env: &FxHashMap<String, String>,
) -> Result<Sysroot> {
tracing::debug!("discovering sysroot for {dir}");
let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
let sysroot_src_dir =
discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env);
Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), false))
}
pub fn discover_with_src_override(
@ -152,33 +179,59 @@ impl Sysroot {
) -> Result<Sysroot> {
tracing::debug!("discovering sysroot for {current_dir}");
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?;
Ok(Sysroot::load(sysroot_dir, src, metadata))
Ok(Sysroot::load(sysroot_dir, Some(Ok(src)), metadata))
}
pub fn discover_rustc_src(&self) -> Option<ManifestPath> {
get_rustc_src(&self.root)
}
pub fn discover_rustc(&self) -> anyhow::Result<AbsPathBuf> {
let rustc = self.root.join("bin/rustc");
tracing::debug!(?rustc, "checking for rustc binary at location");
match fs::metadata(&rustc) {
Ok(_) => Ok(rustc),
Err(e) => Err(e).context(format!(
"failed to discover rustc in sysroot: {:?}",
AsRef::<std::path::Path>::as_ref(&self.root)
)),
}
}
pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Result<Sysroot> {
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir).ok_or_else(|| {
format_err!("can't load standard library from sysroot path {sysroot_dir}")
})?;
Ok(Sysroot::load(sysroot_dir, sysroot_src_dir, metadata))
});
Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata))
}
pub fn load(sysroot_dir: AbsPathBuf, sysroot_src_dir: AbsPathBuf, metadata: bool) -> Sysroot {
pub fn set_rustup_toolchain_env(cmd: &mut Command, sysroot: Option<&Self>) {
if let Some(sysroot) = sysroot {
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
}
}
pub fn discover_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {
["libexec", "lib"]
.into_iter()
.map(|segment| self.root().join(segment).join("rust-analyzer-proc-macro-srv"))
.find_map(|server_path| probe_for_binary(server_path.into()))
.map(AbsPathBuf::assert)
.ok_or_else(|| {
anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", self.root())
})
}
pub fn load(
sysroot_dir: AbsPathBuf,
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
metadata: bool,
) -> Sysroot {
let sysroot_src_dir = match sysroot_src_dir {
Some(Ok(sysroot_src_dir)) => sysroot_src_dir,
Some(Err(e)) => {
return Sysroot {
root: sysroot_dir,
src_root: Some(Err(Arc::new(e))),
mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }),
}
}
None => {
return Sysroot {
root: sysroot_dir,
src_root: None,
mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }),
}
}
};
if metadata {
let sysroot: Option<_> = (|| {
let sysroot_cargo_toml = ManifestPath::try_from(
@ -187,10 +240,19 @@ impl Sysroot {
.ok()?;
let current_dir =
AbsPathBuf::try_from(&*format!("{sysroot_src_dir}/sysroot")).ok()?;
let mut cargo_config = CargoConfig::default();
// the sysroot uses `public-dependency`, so we make cargo think it's a nightly
cargo_config.extra_env.insert(
"__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS".to_owned(),
"nightly".to_owned(),
);
let res = CargoWorkspace::fetch_metadata(
&sysroot_cargo_toml,
&current_dir,
&CargoConfig::default(),
&cargo_config,
None,
&|_| (),
)
.map_err(|e| {
@ -274,7 +336,7 @@ impl Sysroot {
let cargo_workspace = CargoWorkspace::new(res);
Some(Sysroot {
root: sysroot_dir.clone(),
src_root: sysroot_src_dir.clone(),
src_root: Some(Ok(sysroot_src_dir.clone())),
mode: SysrootMode::Workspace(cargo_workspace),
})
})();
@ -326,7 +388,7 @@ impl Sysroot {
}
Sysroot {
root: sysroot_dir,
src_root: sysroot_src_dir,
src_root: Some(Ok(sysroot_src_dir)),
mode: SysrootMode::Stitched(stitched),
}
}

View file

@ -3,38 +3,58 @@ use std::process::Command;
use rustc_hash::FxHashMap;
use crate::{utf8_stdout, ManifestPath};
use crate::{utf8_stdout, ManifestPath, Sysroot};
/// Determines how `rustc --print target-spec-json` is discovered and invoked.
pub enum RustcDataLayoutConfig<'a> {
/// Use `rustc --print target-spec-json`, either from with the binary from the sysroot or by discovering via
/// [`toolchain::rustc`].
Rustc(Option<&'a Sysroot>),
/// Use `cargo --print target-spec-json`, either from with the binary from the sysroot or by discovering via
/// [`toolchain::cargo`].
Cargo(Option<&'a Sysroot>, &'a ManifestPath),
}
pub fn get(
cargo_toml: Option<&ManifestPath>,
config: RustcDataLayoutConfig<'_>,
target: Option<&str>,
extra_env: &FxHashMap<String, String>,
) -> anyhow::Result<String> {
let output = (|| {
if let Some(cargo_toml) = cargo_toml {
let mut cmd = Command::new(toolchain::rustc());
let process = |output: String| {
(|| Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned()))()
.ok_or_else(|| {
anyhow::format_err!("could not fetch target-spec-json from command output")
})
};
let sysroot = match config {
RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
let mut cmd = Command::new(toolchain::Tool::Cargo.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env);
cmd.current_dir(cargo_toml.parent())
.args(["-Z", "unstable-options", "--print", "target-spec-json"])
.args(["rustc", "--", "-Z", "unstable-options", "--print", "target-spec-json"])
.env("RUSTC_BOOTSTRAP", "1");
if let Some(target) = target {
cmd.args(["--target", target]);
}
match utf8_stdout(cmd) {
Ok(it) => return Ok(it),
Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
Ok(output) => return process(output),
Err(e) => {
tracing::warn!("failed to run `cargo rustc --print target-spec-json`, falling back to invoking rustc directly: {e}");
sysroot
}
}
}
// using unstable cargo features failed, fall back to using plain rustc
let mut cmd = Command::new(toolchain::rustc());
cmd.envs(extra_env)
.args(["-Z", "unstable-options", "--print", "target-spec-json"])
.env("RUSTC_BOOTSTRAP", "1");
if let Some(target) = target {
cmd.args(["--target", target]);
}
utf8_stdout(cmd)
})()?;
(|| Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned()))()
.ok_or_else(|| anyhow::format_err!("could not fetch target-spec-json from command output"))
RustcDataLayoutConfig::Rustc(sysroot) => sysroot,
};
let mut cmd = Command::new(toolchain::Tool::Rustc.path());
Sysroot::set_rustup_toolchain_env(&mut cmd, sysroot);
cmd.envs(extra_env)
.args(["-Z", "unstable-options", "--print", "target-spec-json"])
.env("RUSTC_BOOTSTRAP", "1");
if let Some(target) = target {
cmd.args(["--target", target]);
}
process(utf8_stdout(cmd)?)
}

View file

@ -9,6 +9,7 @@ use expect_test::{expect_file, ExpectFile};
use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap;
use serde::de::DeserializeOwned;
use triomphe::Arc;
use crate::{
CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot,
@ -34,6 +35,7 @@ fn load_cargo_with_overrides(
cfg_overrides,
toolchain: None,
target_layout: Err("target_data_layout not loaded".into()),
cargo_config_extra_env: Default::default(),
};
to_crate_graph(project_workspace)
}
@ -53,6 +55,7 @@ fn load_cargo_with_fake_sysroot(
cfg_overrides: Default::default(),
toolchain: None,
target_layout: Err("target_data_layout not loaded".into()),
cargo_config_extra_env: Default::default(),
};
project_workspace.to_crate_graph(
&mut {
@ -69,8 +72,13 @@ fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
let data = get_test_json_file(file);
let project = rooted_project_json(data);
let sysroot = Ok(get_fake_sysroot());
let project_workspace =
ProjectWorkspace::Json { project, sysroot, rustc_cfg: Vec::new(), toolchain: None };
let project_workspace = ProjectWorkspace::Json {
project,
sysroot,
rustc_cfg: Vec::new(),
toolchain: None,
target_layout: Err(Arc::from("test has no data layout")),
};
to_crate_graph(project_workspace)
}
@ -125,7 +133,7 @@ fn get_fake_sysroot() -> Sysroot {
// fake sysroot, so we give them both the same path:
let sysroot_dir = AbsPathBuf::assert(sysroot_path);
let sysroot_src_dir = sysroot_dir.clone();
Sysroot::load(sysroot_dir, sysroot_src_dir, false)
Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false)
}
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
@ -230,7 +238,7 @@ fn crate_graph_dedup_identical() {
let (d_crate_graph, mut d_proc_macros) = (crate_graph.clone(), proc_macros.clone());
crate_graph.extend(d_crate_graph.clone(), &mut d_proc_macros, |_| ());
crate_graph.extend(d_crate_graph.clone(), &mut d_proc_macros, |(_, a), (_, b)| a == b);
assert!(crate_graph.iter().eq(d_crate_graph.iter()));
assert_eq!(proc_macros, d_proc_macros);
}
@ -246,62 +254,10 @@ fn crate_graph_dedup() {
load_cargo_with_fake_sysroot(path_map, "regex-metadata.json");
assert_eq!(regex_crate_graph.iter().count(), 60);
crate_graph.extend(regex_crate_graph, &mut regex_proc_macros, |_| ());
crate_graph.extend(regex_crate_graph, &mut regex_proc_macros, |(_, a), (_, b)| a == b);
assert_eq!(crate_graph.iter().count(), 118);
}
#[test]
fn test_deduplicate_origin_dev() {
let path_map = &mut Default::default();
let (mut crate_graph, _proc_macros) =
load_cargo_with_fake_sysroot(path_map, "deduplication_crate_graph_A.json");
crate_graph.sort_deps();
let (crate_graph_1, mut _proc_macros_2) =
load_cargo_with_fake_sysroot(path_map, "deduplication_crate_graph_B.json");
crate_graph.extend(crate_graph_1, &mut _proc_macros_2, |_| ());
let mut crates_named_p2 = vec![];
for id in crate_graph.iter() {
let krate = &crate_graph[id];
if let Some(name) = krate.display_name.as_ref() {
if name.to_string() == "p2" {
crates_named_p2.push(krate);
}
}
}
assert!(crates_named_p2.len() == 1);
let p2 = crates_named_p2[0];
assert!(p2.origin.is_local());
}
#[test]
fn test_deduplicate_origin_dev_rev() {
let path_map = &mut Default::default();
let (mut crate_graph, _proc_macros) =
load_cargo_with_fake_sysroot(path_map, "deduplication_crate_graph_B.json");
crate_graph.sort_deps();
let (crate_graph_1, mut _proc_macros_2) =
load_cargo_with_fake_sysroot(path_map, "deduplication_crate_graph_A.json");
crate_graph.extend(crate_graph_1, &mut _proc_macros_2, |_| ());
let mut crates_named_p2 = vec![];
for id in crate_graph.iter() {
let krate = &crate_graph[id];
if let Some(name) = krate.display_name.as_ref() {
if name.to_string() == "p2" {
crates_named_p2.push(krate);
}
}
}
assert!(crates_named_p2.len() == 1);
let p2 = crates_named_p2[0];
assert!(p2.origin.is_local());
}
#[test]
fn smoke_test_real_sysroot_cargo() {
if std::env::var("SYSROOT_CARGO_METADATA").is_err() {
@ -327,6 +283,7 @@ fn smoke_test_real_sysroot_cargo() {
cfg_overrides: Default::default(),
toolchain: None,
target_layout: Err("target_data_layout not loaded".into()),
cargo_config_extra_env: Default::default(),
};
project_workspace.to_crate_graph(
&mut {

File diff suppressed because it is too large Load diff

View file

@ -1,140 +0,0 @@
{
"packages": [
{
"name": "p1",
"version": "0.1.0",
"id": "p1 0.1.0 (path+file:///example_project/p1)",
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [
{
"name": "p2",
"source": null,
"req": "*",
"kind": null,
"rename": null,
"optional": false,
"uses_default_features": true,
"features": [],
"target": null,
"registry": null,
"path": "$ROOT$example_project/p2"
}
],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "p1",
"src_path": "$ROOT$example_project/p1/src/lib.rs",
"edition": "2021",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "$ROOT$example_project/p1/Cargo.toml",
"metadata": null,
"publish": null,
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2021",
"links": null,
"default_run": null,
"rust_version": null
},
{
"name": "p2",
"version": "0.1.0",
"id": "p2 0.1.0 (path+file:///example_project/p2)",
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "p2",
"src_path": "$ROOT$example_project/p2/src/lib.rs",
"edition": "2021",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "$ROOT$example_project/p2/Cargo.toml",
"metadata": null,
"publish": null,
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2021",
"links": null,
"default_run": null,
"rust_version": null
}
],
"workspace_members": [
"p1 0.1.0 (path+file:///example_project/p1)"
],
"workspace_default_members": [
"p1 0.1.0 (path+file:///example_project/p1)"
],
"resolve": {
"nodes": [
{
"id": "p1 0.1.0 (path+file:///example_project/p1)",
"dependencies": [
"p2 0.1.0 (path+file:///example_project/p2)"
],
"deps": [
{
"name": "p2",
"pkg": "p2 0.1.0 (path+file:///example_project/p2)",
"dep_kinds": [
{
"kind": null,
"target": null
}
]
}
],
"features": []
},
{
"id": "p2 0.1.0 (path+file:///example_project/p2)",
"dependencies": [],
"deps": [],
"features": []
}
],
"root": "p1 0.1.0 (path+file:///example_project/p1)"
},
"target_directory": "$ROOT$example_project/p1/target",
"version": 1,
"workspace_root": "$ROOT$example_project/p1",
"metadata": null
}

View file

@ -1,66 +0,0 @@
{
"packages": [
{
"name": "p2",
"version": "0.1.0",
"id": "p2 0.1.0 (path+file:///example_project/p2)",
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [],
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"name": "p2",
"src_path": "$ROOT$example_project/p2/src/lib.rs",
"edition": "2021",
"doc": true,
"doctest": true,
"test": true
}
],
"features": {},
"manifest_path": "$ROOT$example_project/p2/Cargo.toml",
"metadata": null,
"publish": null,
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2021",
"links": null,
"default_run": null,
"rust_version": null
}
],
"workspace_members": [
"p2 0.1.0 (path+file:///example_project/p2)"
],
"workspace_default_members": [
"p2 0.1.0 (path+file:///example_project/p2)"
],
"resolve": {
"nodes": [
{
"id": "p2 0.1.0 (path+file:///example_project/p2)",
"dependencies": [],
"deps": [],
"features": []
}
],
"root": "p2 0.1.0 (path+file:///example_project/p2)"
},
"target_directory": "$ROOT$example_project/p2/target",
"version": 1,
"workspace_root": "$ROOT$example_project/p2",
"metadata": null
}

View file

@ -48,7 +48,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -59,10 +58,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
1: CrateData {
root_file_id: FileId(
@ -113,7 +108,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -121,7 +115,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -132,10 +125,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
2: CrateData {
root_file_id: FileId(
@ -186,7 +175,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -194,7 +182,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -205,10 +192,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
3: CrateData {
root_file_id: FileId(
@ -259,7 +242,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -267,7 +249,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -278,10 +259,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
4: CrateData {
root_file_id: FileId(
@ -347,9 +324,5 @@
name: "libc",
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
}

View file

@ -48,7 +48,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -59,10 +58,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
1: CrateData {
root_file_id: FileId(
@ -113,7 +108,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -121,7 +115,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -132,10 +125,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
2: CrateData {
root_file_id: FileId(
@ -186,7 +175,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -194,7 +182,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -205,10 +192,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
3: CrateData {
root_file_id: FileId(
@ -259,7 +242,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -267,7 +249,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -278,10 +259,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
4: CrateData {
root_file_id: FileId(
@ -347,9 +324,5 @@
name: "libc",
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
}

View file

@ -47,7 +47,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -58,10 +57,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
1: CrateData {
root_file_id: FileId(
@ -111,7 +106,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -119,7 +113,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -130,10 +123,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
2: CrateData {
root_file_id: FileId(
@ -183,7 +172,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -191,7 +179,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -202,10 +189,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
3: CrateData {
root_file_id: FileId(
@ -255,7 +238,6 @@
name: CrateName(
"hello_world",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -263,7 +245,6 @@
name: CrateName(
"libc",
),
kind: Normal,
prelude: true,
},
],
@ -274,10 +255,6 @@
),
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
4: CrateData {
root_file_id: FileId(
@ -343,9 +320,5 @@
name: "libc",
},
is_proc_macro: false,
target_layout: Err(
"target_data_layout not loaded",
),
toolchain: None,
},
}

View file

@ -28,7 +28,6 @@
name: CrateName(
"core",
),
kind: Normal,
prelude: true,
},
],
@ -36,10 +35,6 @@
Alloc,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
1: CrateData {
root_file_id: FileId(
@ -69,10 +64,6 @@
Core,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
2: CrateData {
root_file_id: FileId(
@ -102,10 +93,6 @@
Other,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
3: CrateData {
root_file_id: FileId(
@ -135,10 +122,6 @@
Other,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
4: CrateData {
root_file_id: FileId(
@ -169,7 +152,6 @@
name: CrateName(
"std",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -177,7 +159,6 @@
name: CrateName(
"core",
),
kind: Normal,
prelude: true,
},
],
@ -185,10 +166,6 @@
ProcMacro,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
5: CrateData {
root_file_id: FileId(
@ -218,10 +195,6 @@
Other,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
6: CrateData {
root_file_id: FileId(
@ -252,7 +225,6 @@
name: CrateName(
"alloc",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -260,7 +232,6 @@
name: CrateName(
"panic_unwind",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -268,7 +239,6 @@
name: CrateName(
"panic_abort",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -276,7 +246,6 @@
name: CrateName(
"core",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -284,7 +253,6 @@
name: CrateName(
"profiler_builtins",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -292,7 +260,6 @@
name: CrateName(
"unwind",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -300,7 +267,6 @@
name: CrateName(
"std_detect",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -308,7 +274,6 @@
name: CrateName(
"test",
),
kind: Normal,
prelude: true,
},
],
@ -316,10 +281,6 @@
Std,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
7: CrateData {
root_file_id: FileId(
@ -349,10 +310,6 @@
Other,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
8: CrateData {
root_file_id: FileId(
@ -382,10 +339,6 @@
Test,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
9: CrateData {
root_file_id: FileId(
@ -415,10 +368,6 @@
Other,
),
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
10: CrateData {
root_file_id: FileId(
@ -449,7 +398,6 @@
name: CrateName(
"core",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -457,7 +405,6 @@
name: CrateName(
"alloc",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -465,7 +412,6 @@
name: CrateName(
"std",
),
kind: Normal,
prelude: true,
},
Dependency {
@ -473,7 +419,6 @@
name: CrateName(
"test",
),
kind: Normal,
prelude: false,
},
Dependency {
@ -481,7 +426,6 @@
name: CrateName(
"proc_macro",
),
kind: Normal,
prelude: false,
},
],
@ -492,9 +436,5 @@
),
},
is_proc_macro: false,
target_layout: Err(
"rust-project.json projects have no target layout set",
),
toolchain: None,
},
}