mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 15:14:32 +00:00
Allow sysroots to only consist of the source root dir
This commit is contained in:
parent
5717622c95
commit
bd37e2790b
18 changed files with 277 additions and 361 deletions
|
@ -1,7 +1,7 @@
|
|||
use chalk_ir::{AdtId, TyKind};
|
||||
use either::Either;
|
||||
use hir_def::db::DefDatabase;
|
||||
use project_model::target_data_layout::RustcDataLayoutConfig;
|
||||
use project_model::{target_data_layout::RustcDataLayoutConfig, Sysroot};
|
||||
use rustc_hash::FxHashMap;
|
||||
use test_fixture::WithFixture;
|
||||
use triomphe::Arc;
|
||||
|
@ -17,7 +17,7 @@ mod closure;
|
|||
|
||||
fn current_machine_data_layout() -> String {
|
||||
project_model::target_data_layout::get(
|
||||
RustcDataLayoutConfig::Rustc(None),
|
||||
RustcDataLayoutConfig::Rustc(&Sysroot::empty()),
|
||||
None,
|
||||
&FxHashMap::default(),
|
||||
)
|
||||
|
|
|
@ -65,7 +65,7 @@ impl WorkspaceBuildScripts {
|
|||
allowed_features: &FxHashSet<String>,
|
||||
manifest_path: &ManifestPath,
|
||||
toolchain: Option<&Version>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> io::Result<Command> {
|
||||
const RUST_1_75: Version = Version::new(1, 75, 0);
|
||||
let mut cmd = match config.run_build_script_command.as_deref() {
|
||||
|
@ -75,7 +75,7 @@ impl WorkspaceBuildScripts {
|
|||
cmd
|
||||
}
|
||||
_ => {
|
||||
let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cmd = sysroot.tool(Tool::Cargo);
|
||||
|
||||
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
|
||||
cmd.args(&config.extra_args);
|
||||
|
@ -149,7 +149,7 @@ impl WorkspaceBuildScripts {
|
|||
workspace: &CargoWorkspace,
|
||||
progress: &dyn Fn(String),
|
||||
toolchain: Option<&Version>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> io::Result<WorkspaceBuildScripts> {
|
||||
let current_dir = match &config.invocation_location {
|
||||
InvocationLocation::Root(root) if config.run_build_script_command.is_some() => {
|
||||
|
@ -195,7 +195,7 @@ impl WorkspaceBuildScripts {
|
|||
// This is not gonna be used anyways, so just construct a dummy here
|
||||
&ManifestPath::try_from(workspace_root.clone()).unwrap(),
|
||||
None,
|
||||
None,
|
||||
&Sysroot::empty(),
|
||||
)?;
|
||||
// NB: Cargo.toml could have been modified between `cargo metadata` and
|
||||
// `cargo check`. We shouldn't assume that package ids we see here are
|
||||
|
@ -412,7 +412,7 @@ impl WorkspaceBuildScripts {
|
|||
rustc: &CargoWorkspace,
|
||||
current_dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Self {
|
||||
let mut bs = WorkspaceBuildScripts::default();
|
||||
for p in rustc.packages() {
|
||||
|
@ -420,7 +420,7 @@ impl WorkspaceBuildScripts {
|
|||
}
|
||||
let res = (|| {
|
||||
let target_libdir = (|| {
|
||||
let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo);
|
||||
cargo_config.envs(extra_env);
|
||||
cargo_config
|
||||
.current_dir(current_dir)
|
||||
|
@ -429,7 +429,7 @@ impl WorkspaceBuildScripts {
|
|||
if let Ok(it) = utf8_stdout(cargo_config) {
|
||||
return Ok(it);
|
||||
}
|
||||
let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
|
||||
let mut cmd = sysroot.tool(Tool::Rustc);
|
||||
cmd.envs(extra_env);
|
||||
cmd.args(["--print", "target-libdir"]);
|
||||
utf8_stdout(cmd)
|
||||
|
|
|
@ -258,12 +258,12 @@ impl CargoWorkspace {
|
|||
cargo_toml: &ManifestPath,
|
||||
current_dir: &AbsPath,
|
||||
config: &CargoConfig,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
progress: &dyn Fn(String),
|
||||
) -> anyhow::Result<cargo_metadata::Metadata> {
|
||||
let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
|
||||
|
||||
let cargo = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let cargo = sysroot.tool(Tool::Cargo);
|
||||
let mut meta = MetadataCommand::new();
|
||||
meta.cargo_path(cargo.get_program());
|
||||
cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default()));
|
||||
|
@ -536,7 +536,7 @@ impl CargoWorkspace {
|
|||
fn find_list_of_build_targets(
|
||||
config: &CargoConfig,
|
||||
cargo_toml: &ManifestPath,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Vec<String> {
|
||||
if let Some(target) = &config.target {
|
||||
return [target.into()].to_vec();
|
||||
|
@ -553,9 +553,9 @@ fn find_list_of_build_targets(
|
|||
fn rustc_discover_host_triple(
|
||||
cargo_toml: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Option<String> {
|
||||
let mut rustc = Sysroot::tool(sysroot, Tool::Rustc);
|
||||
let mut rustc = sysroot.tool(Tool::Rustc);
|
||||
rustc.envs(extra_env);
|
||||
rustc.current_dir(cargo_toml.parent()).arg("-vV");
|
||||
tracing::debug!("Discovering host platform by {:?}", rustc);
|
||||
|
@ -581,9 +581,9 @@ fn rustc_discover_host_triple(
|
|||
fn cargo_config_build_target(
|
||||
cargo_toml: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Vec<String> {
|
||||
let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo);
|
||||
cargo_config.envs(extra_env);
|
||||
cargo_config
|
||||
.current_dir(cargo_toml.parent())
|
||||
|
|
|
@ -62,9 +62,9 @@ pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: Targe
|
|||
pub(crate) fn cargo_config_env(
|
||||
manifest: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
) -> FxHashMap<String, String> {
|
||||
let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo);
|
||||
cargo_config.envs(extra_env);
|
||||
cargo_config
|
||||
.current_dir(manifest.parent())
|
||||
|
|
|
@ -10,10 +10,10 @@ use crate::{cfg::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
|
|||
pub(crate) enum RustcCfgConfig<'a> {
|
||||
/// Use `rustc --print cfg`, either from with the binary from the sysroot or by discovering via
|
||||
/// [`toolchain::rustc`].
|
||||
Rustc(Option<&'a Sysroot>),
|
||||
Rustc(&'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),
|
||||
Cargo(&'a Sysroot, &'a ManifestPath),
|
||||
}
|
||||
|
||||
pub(crate) fn get(
|
||||
|
@ -65,7 +65,7 @@ fn get_rust_cfgs(
|
|||
) -> anyhow::Result<String> {
|
||||
let sysroot = match config {
|
||||
RustcCfgConfig::Cargo(sysroot, cargo_toml) => {
|
||||
let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cmd = sysroot.tool(Tool::Cargo);
|
||||
|
||||
cmd.envs(extra_env);
|
||||
cmd.current_dir(cargo_toml.parent())
|
||||
|
@ -86,7 +86,7 @@ fn get_rust_cfgs(
|
|||
RustcCfgConfig::Rustc(sysroot) => sysroot,
|
||||
};
|
||||
|
||||
let mut cmd = Sysroot::tool(sysroot, Tool::Rustc);
|
||||
let mut cmd = sysroot.tool(Tool::Rustc);
|
||||
cmd.envs(extra_env);
|
||||
cmd.args(["--print", "cfg", "-O"]);
|
||||
if let Some(target) = target {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! 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, ops, process::Command, sync::Arc};
|
||||
use std::{env, fs, ops, process::Command};
|
||||
|
||||
use anyhow::{format_err, Result};
|
||||
use base_db::CrateName;
|
||||
|
@ -16,30 +16,19 @@ use toolchain::{probe_for_binary, Tool};
|
|||
|
||||
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Sysroot {
|
||||
root: AbsPathBuf,
|
||||
src_root: Option<Result<AbsPathBuf, Arc<anyhow::Error>>>,
|
||||
root: Option<AbsPathBuf>,
|
||||
src_root: Option<AbsPathBuf>,
|
||||
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,
|
||||
}
|
||||
}
|
||||
error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum SysrootMode {
|
||||
Workspace(CargoWorkspace),
|
||||
Stitched(Stitched),
|
||||
Empty,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
|
@ -89,70 +78,40 @@ pub(crate) struct SysrootCrateData {
|
|||
}
|
||||
|
||||
impl Sysroot {
|
||||
pub const fn empty() -> Sysroot {
|
||||
Sysroot { root: None, src_root: None, mode: SysrootMode::Empty, error: None }
|
||||
}
|
||||
|
||||
/// Returns sysroot "root" directory, where `bin/`, `etc/`, `lib/`, `libexec/`
|
||||
/// subfolder live, like:
|
||||
/// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu`
|
||||
pub fn root(&self) -> &AbsPath {
|
||||
&self.root
|
||||
pub fn root(&self) -> Option<&AbsPath> {
|
||||
self.root.as_deref()
|
||||
}
|
||||
|
||||
/// 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) -> Option<&AbsPath> {
|
||||
self.src_root.as_ref()?.as_deref().ok()
|
||||
self.src_root.as_deref()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match &self.mode {
|
||||
SysrootMode::Workspace(ws) => ws.packages().next().is_none(),
|
||||
SysrootMode::Stitched(stitched) => stitched.crates.is_empty(),
|
||||
SysrootMode::Empty => true,
|
||||
}
|
||||
}
|
||||
|
||||
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(),
|
||||
};
|
||||
if !has_core {
|
||||
let var_note = if env::var_os("RUST_SRC_PATH").is_some() {
|
||||
" (`RUST_SRC_PATH` might be incorrect, try unsetting it)"
|
||||
} else {
|
||||
" try running `rustup component add rust-src` to possible fix this"
|
||||
};
|
||||
Some(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_has_core(&self) -> Result<(), String> {
|
||||
let Some(Ok(src_root)) = &self.src_root else { return Ok(()) };
|
||||
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(),
|
||||
};
|
||||
if !has_core {
|
||||
let var_note = if env::var_os("RUST_SRC_PATH").is_some() {
|
||||
" (`RUST_SRC_PATH` might be incorrect, try unsetting it)"
|
||||
} else {
|
||||
" try running `rustup component add rust-src` to possible fix this"
|
||||
};
|
||||
Err(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
pub fn error(&self) -> Option<&str> {
|
||||
self.error.as_deref()
|
||||
}
|
||||
|
||||
pub fn num_packages(&self) -> usize {
|
||||
match &self.mode {
|
||||
SysrootMode::Workspace(ws) => ws.packages().count(),
|
||||
SysrootMode::Stitched(c) => c.crates().count(),
|
||||
SysrootMode::Empty => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,63 +127,50 @@ impl Sysroot {
|
|||
dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
metadata: bool,
|
||||
) -> 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), 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))
|
||||
) -> Sysroot {
|
||||
let sysroot_dir = discover_sysroot_dir(dir, extra_env);
|
||||
let sysroot_src_dir = sysroot_dir.as_ref().ok().map(|sysroot_dir| {
|
||||
discover_sysroot_src_dir_or_add_component(sysroot_dir, dir, extra_env)
|
||||
});
|
||||
Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir, metadata)
|
||||
}
|
||||
|
||||
pub fn discover_with_src_override(
|
||||
current_dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
src: AbsPathBuf,
|
||||
sysroot_src_dir: AbsPathBuf,
|
||||
metadata: bool,
|
||||
) -> Result<Sysroot> {
|
||||
tracing::debug!("discovering sysroot for {current_dir}");
|
||||
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?;
|
||||
Ok(Sysroot::load(sysroot_dir, Some(Ok(src)), metadata))
|
||||
) -> Sysroot {
|
||||
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env);
|
||||
Sysroot::load_core_check(Some(sysroot_dir), Some(Ok(sysroot_src_dir)), metadata)
|
||||
}
|
||||
|
||||
pub fn discover_sysroot_src_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Sysroot {
|
||||
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir)
|
||||
.ok_or_else(|| format_err!("can't find standard library sources in {sysroot_dir}"));
|
||||
Sysroot::load_core_check(Some(Ok(sysroot_dir)), Some(sysroot_src_dir), metadata)
|
||||
}
|
||||
|
||||
pub fn discover_rustc_src(&self) -> Option<ManifestPath> {
|
||||
get_rustc_src(&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, Some(sysroot_src_dir), metadata))
|
||||
get_rustc_src(self.root()?)
|
||||
}
|
||||
|
||||
/// Returns a command to run a tool preferring the cargo proxies if the sysroot exists.
|
||||
pub fn tool(sysroot: Option<&Self>, tool: Tool) -> Command {
|
||||
match sysroot {
|
||||
Some(sysroot) => {
|
||||
pub fn tool(&self, tool: Tool) -> Command {
|
||||
match self.root() {
|
||||
Some(root) => {
|
||||
// special case rustc, we can look that up directly in the sysroot's bin folder
|
||||
// as it should never invoke another cargo binary
|
||||
if let Tool::Rustc = tool {
|
||||
if let Some(path) =
|
||||
probe_for_binary(sysroot.root.join("bin").join(Tool::Rustc.name()).into())
|
||||
probe_for_binary(root.join("bin").join(Tool::Rustc.name()).into())
|
||||
{
|
||||
return Command::new(path);
|
||||
}
|
||||
}
|
||||
|
||||
let mut cmd = Command::new(tool.prefer_proxy());
|
||||
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(&sysroot.root));
|
||||
cmd.env("RUSTUP_TOOLCHAIN", AsRef::<std::path::Path>::as_ref(root));
|
||||
cmd
|
||||
}
|
||||
_ => Command::new(tool.path()),
|
||||
|
@ -232,35 +178,89 @@ impl Sysroot {
|
|||
}
|
||||
|
||||
pub fn discover_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {
|
||||
let Some(root) = self.root() else {
|
||||
return Err(anyhow::format_err!("no sysroot",));
|
||||
};
|
||||
["libexec", "lib"]
|
||||
.into_iter()
|
||||
.map(|segment| self.root().join(segment).join("rust-analyzer-proc-macro-srv"))
|
||||
.map(|segment| 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())
|
||||
anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", root)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
sysroot_dir: AbsPathBuf,
|
||||
sysroot_dir: Option<AbsPathBuf>,
|
||||
sysroot_src_dir: Option<AbsPathBuf>,
|
||||
metadata: bool,
|
||||
) -> Sysroot {
|
||||
Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), metadata)
|
||||
}
|
||||
|
||||
fn load_core_check(
|
||||
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
metadata: bool,
|
||||
) -> Sysroot {
|
||||
let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, metadata);
|
||||
if sysroot.error.is_none() {
|
||||
if let Some(src_root) = &sysroot.src_root {
|
||||
let has_core = match &sysroot.mode {
|
||||
SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"),
|
||||
SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(),
|
||||
SysrootMode::Empty => true,
|
||||
};
|
||||
if !has_core {
|
||||
let var_note = if env::var_os("RUST_SRC_PATH").is_some() {
|
||||
" (env var `RUST_SRC_PATH` is set and may be incorrect, try unsetting it)"
|
||||
} else {
|
||||
", try running `rustup component add rust-src` to possibly fix this"
|
||||
};
|
||||
sysroot.error = Some(format!(
|
||||
"sysroot at `{}` is missing a `core` library{var_note}",
|
||||
src_root,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
sysroot
|
||||
}
|
||||
|
||||
fn load_(
|
||||
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
metadata: bool,
|
||||
) -> Sysroot {
|
||||
let sysroot_dir = match sysroot_dir {
|
||||
Some(Ok(sysroot_dir)) => Some(sysroot_dir),
|
||||
Some(Err(e)) => {
|
||||
return Sysroot {
|
||||
root: None,
|
||||
src_root: None,
|
||||
mode: SysrootMode::Empty,
|
||||
error: Some(e.to_string()),
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
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() }),
|
||||
src_root: None,
|
||||
mode: SysrootMode::Empty,
|
||||
error: Some(e.to_string()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Sysroot {
|
||||
root: sysroot_dir,
|
||||
src_root: None,
|
||||
mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }),
|
||||
mode: SysrootMode::Empty,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -284,7 +284,7 @@ impl Sysroot {
|
|||
&sysroot_cargo_toml,
|
||||
¤t_dir,
|
||||
&cargo_config,
|
||||
None,
|
||||
&Sysroot::empty(),
|
||||
&|_| (),
|
||||
)
|
||||
.map_err(|e| {
|
||||
|
@ -368,8 +368,9 @@ impl Sysroot {
|
|||
let cargo_workspace = CargoWorkspace::new(res, sysroot_cargo_toml);
|
||||
Some(Sysroot {
|
||||
root: sysroot_dir.clone(),
|
||||
src_root: Some(Ok(sysroot_src_dir.clone())),
|
||||
src_root: Some(sysroot_src_dir.clone()),
|
||||
mode: SysrootMode::Workspace(cargo_workspace),
|
||||
error: None,
|
||||
})
|
||||
})();
|
||||
if let Some(sysroot) = sysroot {
|
||||
|
@ -420,8 +421,9 @@ impl Sysroot {
|
|||
}
|
||||
Sysroot {
|
||||
root: sysroot_dir,
|
||||
src_root: Some(Ok(sysroot_src_dir)),
|
||||
src_root: Some(sysroot_src_dir),
|
||||
mode: SysrootMode::Stitched(stitched),
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ use crate::{utf8_stdout, ManifestPath, Sysroot};
|
|||
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>),
|
||||
Rustc(&'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),
|
||||
Cargo(&'a Sysroot, &'a ManifestPath),
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
|
@ -28,7 +28,7 @@ pub fn get(
|
|||
};
|
||||
let sysroot = match config {
|
||||
RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => {
|
||||
let mut cmd = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
let mut cmd = sysroot.tool(Tool::Cargo);
|
||||
cmd.envs(extra_env);
|
||||
cmd.current_dir(cargo_toml.parent())
|
||||
.args([
|
||||
|
|
|
@ -34,7 +34,7 @@ fn load_cargo_with_overrides(
|
|||
cargo_config_extra_env: Default::default(),
|
||||
},
|
||||
cfg_overrides,
|
||||
sysroot: Err(None),
|
||||
sysroot: Sysroot::empty(),
|
||||
rustc_cfg: Vec::new(),
|
||||
toolchain: None,
|
||||
target_layout: Err("target_data_layout not loaded".into()),
|
||||
|
@ -57,7 +57,7 @@ fn load_cargo_with_fake_sysroot(
|
|||
rustc: Err(None),
|
||||
cargo_config_extra_env: Default::default(),
|
||||
},
|
||||
sysroot: Ok(get_fake_sysroot()),
|
||||
sysroot: get_fake_sysroot(),
|
||||
rustc_cfg: Vec::new(),
|
||||
cfg_overrides: Default::default(),
|
||||
toolchain: None,
|
||||
|
@ -77,7 +77,7 @@ fn load_cargo_with_fake_sysroot(
|
|||
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 sysroot = get_fake_sysroot();
|
||||
let project_workspace = ProjectWorkspace {
|
||||
kind: ProjectWorkspaceKind::Json(project),
|
||||
sysroot,
|
||||
|
@ -144,7 +144,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, Some(Ok(sysroot_src_dir)), false)
|
||||
Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false)
|
||||
}
|
||||
|
||||
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
||||
|
@ -281,12 +281,11 @@ fn smoke_test_real_sysroot_cargo() {
|
|||
let manifest_path =
|
||||
ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
|
||||
let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
|
||||
let sysroot = Ok(Sysroot::discover(
|
||||
let sysroot = Sysroot::discover(
|
||||
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
|
||||
&Default::default(),
|
||||
true,
|
||||
)
|
||||
.unwrap());
|
||||
);
|
||||
|
||||
let project_workspace = ProjectWorkspace {
|
||||
kind: ProjectWorkspaceKind::Cargo {
|
||||
|
|
|
@ -48,7 +48,7 @@ pub struct PackageRoot {
|
|||
pub struct ProjectWorkspace {
|
||||
pub kind: ProjectWorkspaceKind,
|
||||
/// The sysroot loaded for this workspace.
|
||||
pub sysroot: Result<Sysroot, Option<String>>,
|
||||
pub sysroot: Sysroot,
|
||||
/// Holds cfg flags for the current target. We get those by running
|
||||
/// `rustc --print cfg`.
|
||||
// FIXME: make this a per-crate map, as, eg, build.rs might have a
|
||||
|
@ -112,7 +112,7 @@ impl fmt::Debug for ProjectWorkspace {
|
|||
.debug_struct("Cargo")
|
||||
.field("root", &cargo.workspace_root().file_name())
|
||||
.field("n_packages", &cargo.packages().len())
|
||||
.field("sysroot", &sysroot.is_ok())
|
||||
.field("n_sysroot_crates", &sysroot.num_packages())
|
||||
.field(
|
||||
"n_rustc_compiler_crates",
|
||||
&rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(rc, _)| rc.packages().len()),
|
||||
|
@ -125,11 +125,9 @@ impl fmt::Debug for ProjectWorkspace {
|
|||
.finish(),
|
||||
ProjectWorkspaceKind::Json(project) => {
|
||||
let mut debug_struct = f.debug_struct("Json");
|
||||
debug_struct.field("n_crates", &project.n_crates());
|
||||
if let Ok(sysroot) = sysroot {
|
||||
debug_struct.field("n_sysroot_crates", &sysroot.num_packages());
|
||||
}
|
||||
debug_struct
|
||||
.field("n_crates", &project.n_crates())
|
||||
.field("n_sysroot_crates", &sysroot.num_packages())
|
||||
.field("n_rustc_cfg", &rustc_cfg.len())
|
||||
.field("toolchain", &toolchain)
|
||||
.field("data_layout", &target_layout)
|
||||
|
@ -144,7 +142,7 @@ impl fmt::Debug for ProjectWorkspace {
|
|||
.debug_struct("DetachedFiles")
|
||||
.field("file", &file)
|
||||
.field("cargo_script", &cargo_script.is_some())
|
||||
.field("sysroot", &sysroot.is_ok())
|
||||
.field("n_sysroot_crates", &sysroot.num_packages())
|
||||
.field("cargo_script", &cargo_script.is_some())
|
||||
.field("n_rustc_cfg", &rustc_cfg.len())
|
||||
.field("toolchain", &toolchain)
|
||||
|
@ -158,7 +156,7 @@ impl fmt::Debug for ProjectWorkspace {
|
|||
|
||||
fn get_toolchain_version(
|
||||
current_dir: &AbsPath,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
tool: Tool,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
prefix: &str,
|
||||
|
@ -213,41 +211,37 @@ impl ProjectWorkspace {
|
|||
}
|
||||
ProjectManifest::CargoToml(cargo_toml) => {
|
||||
let sysroot = match (&config.sysroot, &config.sysroot_src) {
|
||||
(Some(RustLibSource::Path(path)), None) => {
|
||||
Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata).map_err(|e| {
|
||||
Some(format!("Failed to find sysroot at {path}:{e}"))
|
||||
})
|
||||
}
|
||||
(Some(RustLibSource::Discover), None) => {
|
||||
Sysroot::discover(cargo_toml.parent(), &config.extra_env, config.sysroot_query_metadata).map_err(|e| {
|
||||
Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}"))
|
||||
})
|
||||
}
|
||||
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => {
|
||||
Ok(Sysroot::load(sysroot.clone(), Some(Ok(sysroot_src.clone())), config.sysroot_query_metadata))
|
||||
}
|
||||
(Some(RustLibSource::Discover), None) => Sysroot::discover(
|
||||
cargo_toml.parent(),
|
||||
&config.extra_env,
|
||||
config.sysroot_query_metadata,
|
||||
),
|
||||
(Some(RustLibSource::Discover), Some(sysroot_src)) => {
|
||||
Sysroot::discover_with_src_override(
|
||||
cargo_toml.parent(),
|
||||
&config.extra_env,
|
||||
sysroot_src.clone(), config.sysroot_query_metadata,
|
||||
).map_err(|e| {
|
||||
Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}"))
|
||||
})
|
||||
sysroot_src.clone(),
|
||||
config.sysroot_query_metadata,
|
||||
)
|
||||
}
|
||||
(None, _) => Err(None),
|
||||
(Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir(
|
||||
path.clone(),
|
||||
config.sysroot_query_metadata,
|
||||
),
|
||||
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load(
|
||||
Some(sysroot.clone()),
|
||||
Some(sysroot_src.clone()),
|
||||
config.sysroot_query_metadata,
|
||||
),
|
||||
(None, _) => Sysroot::empty(),
|
||||
};
|
||||
let sysroot_ref = sysroot.as_ref().ok();
|
||||
|
||||
if let Ok(sysroot) = &sysroot {
|
||||
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = %sysroot.root(), "Using sysroot");
|
||||
}
|
||||
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
|
||||
|
||||
let rustc_dir = match &config.rustc_source {
|
||||
Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone())
|
||||
.map_err(|p| Some(format!("rustc source path is not absolute: {p}"))),
|
||||
Some(RustLibSource::Discover) => {
|
||||
sysroot_ref.and_then(Sysroot::discover_rustc_src).ok_or_else(|| {
|
||||
sysroot.discover_rustc_src().ok_or_else(|| {
|
||||
Some("Failed to discover rustc source for sysroot.".to_owned())
|
||||
})
|
||||
}
|
||||
|
@ -263,7 +257,7 @@ impl ProjectWorkspace {
|
|||
features: crate::CargoFeatures::default(),
|
||||
..config.clone()
|
||||
},
|
||||
sysroot_ref,
|
||||
&sysroot,
|
||||
progress,
|
||||
) {
|
||||
Ok(meta) => {
|
||||
|
@ -272,7 +266,7 @@ impl ProjectWorkspace {
|
|||
&workspace,
|
||||
cargo_toml.parent(),
|
||||
&config.extra_env,
|
||||
sysroot_ref
|
||||
&sysroot
|
||||
);
|
||||
Ok(Box::new((workspace, buildscripts)))
|
||||
}
|
||||
|
@ -290,7 +284,7 @@ impl ProjectWorkspace {
|
|||
|
||||
let toolchain = get_toolchain_version(
|
||||
cargo_toml.parent(),
|
||||
sysroot_ref,
|
||||
&sysroot,
|
||||
Tool::Cargo,
|
||||
&config.extra_env,
|
||||
"cargo ",
|
||||
|
@ -298,12 +292,12 @@ impl ProjectWorkspace {
|
|||
let rustc_cfg = rustc_cfg::get(
|
||||
config.target.as_deref(),
|
||||
&config.extra_env,
|
||||
RustcCfgConfig::Cargo(sysroot_ref, cargo_toml),
|
||||
RustcCfgConfig::Cargo(&sysroot, cargo_toml),
|
||||
);
|
||||
|
||||
let cfg_overrides = config.cfg_overrides.clone();
|
||||
let data_layout = target_data_layout::get(
|
||||
RustcDataLayoutConfig::Cargo(sysroot_ref, cargo_toml),
|
||||
RustcDataLayoutConfig::Cargo(&sysroot, cargo_toml),
|
||||
config.target.as_deref(),
|
||||
&config.extra_env,
|
||||
);
|
||||
|
@ -315,7 +309,7 @@ impl ProjectWorkspace {
|
|||
cargo_toml,
|
||||
cargo_toml.parent(),
|
||||
config,
|
||||
sysroot_ref,
|
||||
&sysroot,
|
||||
progress,
|
||||
)
|
||||
.with_context(|| {
|
||||
|
@ -326,7 +320,7 @@ impl ProjectWorkspace {
|
|||
let cargo = CargoWorkspace::new(meta, cargo_toml.clone());
|
||||
|
||||
let cargo_config_extra_env =
|
||||
cargo_config_env(cargo_toml, &config.extra_env, sysroot_ref);
|
||||
cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
|
||||
ProjectWorkspace {
|
||||
kind: ProjectWorkspaceKind::Cargo {
|
||||
cargo,
|
||||
|
@ -354,32 +348,13 @@ impl ProjectWorkspace {
|
|||
extra_env: &FxHashMap<String, String>,
|
||||
cfg_overrides: &CfgOverrides,
|
||||
) -> ProjectWorkspace {
|
||||
let sysroot = match (project_json.sysroot.clone(), project_json.sysroot_src.clone()) {
|
||||
(Some(sysroot), Some(sysroot_src)) => {
|
||||
Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false))
|
||||
}
|
||||
(Some(sysroot), None) => {
|
||||
// assume sysroot is structured like rustup's and guess `sysroot_src`
|
||||
let sysroot_src =
|
||||
sysroot.join("lib").join("rustlib").join("src").join("rust").join("library");
|
||||
Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false))
|
||||
}
|
||||
(None, Some(sysroot_src)) => {
|
||||
// assume sysroot is structured like rustup's and guess `sysroot`
|
||||
let mut sysroot = sysroot_src.clone();
|
||||
for _ in 0..5 {
|
||||
sysroot.pop();
|
||||
}
|
||||
Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false))
|
||||
}
|
||||
(None, None) => Err(None),
|
||||
};
|
||||
let sysroot_ref = sysroot.as_ref().ok();
|
||||
let cfg_config = RustcCfgConfig::Rustc(sysroot_ref);
|
||||
let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref);
|
||||
let sysroot =
|
||||
Sysroot::load(project_json.sysroot.clone(), project_json.sysroot_src.clone(), false);
|
||||
let cfg_config = RustcCfgConfig::Rustc(&sysroot);
|
||||
let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot);
|
||||
let toolchain = match get_toolchain_version(
|
||||
project_json.path(),
|
||||
sysroot_ref,
|
||||
&sysroot,
|
||||
Tool::Rustc,
|
||||
extra_env,
|
||||
"rustc ",
|
||||
|
@ -410,24 +385,16 @@ impl ProjectWorkspace {
|
|||
let dir = detached_file.parent();
|
||||
let sysroot = match &config.sysroot {
|
||||
Some(RustLibSource::Path(path)) => {
|
||||
Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata)
|
||||
.map_err(|e| Some(format!("Failed to find sysroot at {path}:{e}")))
|
||||
Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata)
|
||||
}
|
||||
Some(RustLibSource::Discover) => Sysroot::discover(
|
||||
dir,
|
||||
&config.extra_env,
|
||||
config.sysroot_query_metadata,
|
||||
)
|
||||
.map_err(|e| {
|
||||
Some(format!("Failed to find sysroot for {dir}. Is rust-src installed? {e}"))
|
||||
}),
|
||||
None => Err(None),
|
||||
Some(RustLibSource::Discover) => {
|
||||
Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata)
|
||||
}
|
||||
None => Sysroot::empty(),
|
||||
};
|
||||
|
||||
let sysroot_ref = sysroot.as_ref().ok();
|
||||
let toolchain =
|
||||
match get_toolchain_version(dir, sysroot_ref, Tool::Rustc, &config.extra_env, "rustc ")
|
||||
{
|
||||
match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") {
|
||||
Ok(it) => it,
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
|
@ -435,25 +402,24 @@ impl ProjectWorkspace {
|
|||
}
|
||||
};
|
||||
|
||||
let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref));
|
||||
let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(&sysroot));
|
||||
let data_layout = target_data_layout::get(
|
||||
RustcDataLayoutConfig::Rustc(sysroot_ref),
|
||||
RustcDataLayoutConfig::Rustc(&sysroot),
|
||||
None,
|
||||
&config.extra_env,
|
||||
);
|
||||
|
||||
let cargo_script =
|
||||
CargoWorkspace::fetch_metadata(detached_file, dir, config, sysroot_ref, &|_| ())
|
||||
.ok()
|
||||
.map(|ws| {
|
||||
CargoWorkspace::fetch_metadata(detached_file, dir, config, &sysroot, &|_| ()).ok().map(
|
||||
|ws| {
|
||||
(
|
||||
CargoWorkspace::new(ws, detached_file.clone()),
|
||||
WorkspaceBuildScripts::default(),
|
||||
)
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
let cargo_config_extra_env =
|
||||
cargo_config_env(detached_file, &config.extra_env, sysroot_ref);
|
||||
let cargo_config_extra_env = cargo_config_env(detached_file, &config.extra_env, &sysroot);
|
||||
Ok(ProjectWorkspace {
|
||||
kind: ProjectWorkspaceKind::DetachedFile {
|
||||
file: detached_file.to_owned(),
|
||||
|
@ -489,7 +455,7 @@ impl ProjectWorkspace {
|
|||
cargo,
|
||||
progress,
|
||||
self.toolchain.as_ref(),
|
||||
self.sysroot.as_ref().ok(),
|
||||
&self.sysroot,
|
||||
)
|
||||
.with_context(|| {
|
||||
format!("Failed to run build scripts for {}", cargo.workspace_root())
|
||||
|
@ -562,17 +528,7 @@ impl ProjectWorkspace {
|
|||
}
|
||||
|
||||
pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result<AbsPathBuf> {
|
||||
match &self.sysroot {
|
||||
Ok(sysroot) => sysroot.discover_proc_macro_srv(),
|
||||
Err(None) => Err(anyhow::format_err!(
|
||||
"cannot find proc-macro server, the workspace `{}` is missing a sysroot",
|
||||
self.manifest_or_root()
|
||||
)),
|
||||
Err(Some(e)) => Err(anyhow::format_err!(
|
||||
"cannot find proc-macro server, the workspace `{}` is missing a sysroot: {e}",
|
||||
self.manifest_or_root()
|
||||
)),
|
||||
}
|
||||
self.sysroot.discover_proc_macro_srv()
|
||||
}
|
||||
|
||||
/// Returns the roots for the current `ProjectWorkspace`
|
||||
|
@ -580,39 +536,37 @@ impl ProjectWorkspace {
|
|||
/// the root is a member of the current workspace
|
||||
pub fn to_roots(&self) -> Vec<PackageRoot> {
|
||||
let mk_sysroot = || {
|
||||
self.sysroot.as_ref().into_iter().flat_map(move |sysroot: &Sysroot| {
|
||||
let mut r = match sysroot.mode() {
|
||||
SysrootMode::Workspace(ws) => ws
|
||||
.packages()
|
||||
.filter_map(|pkg| {
|
||||
if ws[pkg].is_local {
|
||||
// the local ones are included in the main `PackageRoot`` below
|
||||
return None;
|
||||
}
|
||||
let pkg_root = ws[pkg].manifest.parent().to_path_buf();
|
||||
let mut r = match self.sysroot.mode() {
|
||||
SysrootMode::Workspace(ws) => ws
|
||||
.packages()
|
||||
.filter_map(|pkg| {
|
||||
if ws[pkg].is_local {
|
||||
// the local ones are included in the main `PackageRoot`` below
|
||||
return None;
|
||||
}
|
||||
let pkg_root = ws[pkg].manifest.parent().to_path_buf();
|
||||
|
||||
let include = vec![pkg_root.clone()];
|
||||
let include = vec![pkg_root.clone()];
|
||||
|
||||
let exclude = vec![
|
||||
pkg_root.join(".git"),
|
||||
pkg_root.join("target"),
|
||||
pkg_root.join("tests"),
|
||||
pkg_root.join("examples"),
|
||||
pkg_root.join("benches"),
|
||||
];
|
||||
Some(PackageRoot { is_local: false, include, exclude })
|
||||
})
|
||||
.collect(),
|
||||
SysrootMode::Stitched(_) => vec![],
|
||||
};
|
||||
let exclude = vec![
|
||||
pkg_root.join(".git"),
|
||||
pkg_root.join("target"),
|
||||
pkg_root.join("tests"),
|
||||
pkg_root.join("examples"),
|
||||
pkg_root.join("benches"),
|
||||
];
|
||||
Some(PackageRoot { is_local: false, include, exclude })
|
||||
})
|
||||
.collect(),
|
||||
SysrootMode::Stitched(_) | SysrootMode::Empty => vec![],
|
||||
};
|
||||
|
||||
r.push(PackageRoot {
|
||||
is_local: false,
|
||||
include: sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(),
|
||||
exclude: Vec::new(),
|
||||
});
|
||||
r
|
||||
})
|
||||
r.push(PackageRoot {
|
||||
is_local: false,
|
||||
include: self.sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(),
|
||||
exclude: Vec::new(),
|
||||
});
|
||||
r
|
||||
};
|
||||
match &self.kind {
|
||||
ProjectWorkspaceKind::Json(project) => project
|
||||
|
@ -731,19 +685,15 @@ impl ProjectWorkspace {
|
|||
}
|
||||
|
||||
pub fn n_packages(&self) -> usize {
|
||||
let sysroot_package_len = self.sysroot.num_packages();
|
||||
match &self.kind {
|
||||
ProjectWorkspaceKind::Json(project) => {
|
||||
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
||||
sysroot_package_len + project.n_crates()
|
||||
}
|
||||
ProjectWorkspaceKind::Json(project) => sysroot_package_len + project.n_crates(),
|
||||
ProjectWorkspaceKind::Cargo { cargo, rustc, .. } => {
|
||||
let rustc_package_len =
|
||||
rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(it, _)| it.packages().len());
|
||||
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
||||
cargo.packages().len() + sysroot_package_len + rustc_package_len
|
||||
}
|
||||
ProjectWorkspaceKind::DetachedFile { cargo: cargo_script, .. } => {
|
||||
let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages());
|
||||
sysroot_package_len
|
||||
+ cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len())
|
||||
}
|
||||
|
@ -764,7 +714,7 @@ impl ProjectWorkspace {
|
|||
rustc_cfg.clone(),
|
||||
load,
|
||||
project,
|
||||
sysroot.as_ref().ok(),
|
||||
sysroot,
|
||||
extra_env,
|
||||
cfg_overrides,
|
||||
),
|
||||
|
@ -780,7 +730,7 @@ impl ProjectWorkspace {
|
|||
load,
|
||||
rustc.as_ref().map(|a| a.as_ref()).ok(),
|
||||
cargo,
|
||||
sysroot.as_ref().ok(),
|
||||
sysroot,
|
||||
rustc_cfg.clone(),
|
||||
cfg_overrides,
|
||||
build_scripts,
|
||||
|
@ -793,7 +743,7 @@ impl ProjectWorkspace {
|
|||
&mut |path| load(path),
|
||||
None,
|
||||
cargo,
|
||||
sysroot.as_ref().ok(),
|
||||
sysroot,
|
||||
rustc_cfg.clone(),
|
||||
cfg_overrides,
|
||||
build_scripts,
|
||||
|
@ -803,7 +753,7 @@ impl ProjectWorkspace {
|
|||
rustc_cfg.clone(),
|
||||
load,
|
||||
file,
|
||||
sysroot.as_ref().ok(),
|
||||
sysroot,
|
||||
cfg_overrides,
|
||||
)
|
||||
},
|
||||
|
@ -811,9 +761,7 @@ impl ProjectWorkspace {
|
|||
),
|
||||
};
|
||||
|
||||
if matches!(sysroot.as_ref().map(|it| it.mode()), Ok(SysrootMode::Stitched(_)))
|
||||
&& crate_graph.patch_cfg_if()
|
||||
{
|
||||
if matches!(sysroot.mode(), SysrootMode::Stitched(_)) && crate_graph.patch_cfg_if() {
|
||||
tracing::debug!("Patched std to depend on cfg-if")
|
||||
} else {
|
||||
tracing::debug!("Did not patch std to depend on cfg-if")
|
||||
|
@ -892,15 +840,14 @@ fn project_json_to_crate_graph(
|
|||
rustc_cfg: Vec<CfgFlag>,
|
||||
load: FileLoader<'_>,
|
||||
project: &ProjectJson,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
override_cfg: &CfgOverrides,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||
let (crate_graph, proc_macros) = &mut res;
|
||||
let sysroot_deps = sysroot
|
||||
.as_ref()
|
||||
.map(|sysroot| sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load));
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
|
||||
let r_a_cfg_flag = CfgFlag::Atom("rust_analyzer".to_owned());
|
||||
let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
|
||||
|
@ -978,11 +925,9 @@ fn project_json_to_crate_graph(
|
|||
|
||||
for (from_idx, krate) in project.crates() {
|
||||
if let Some(&from) = idx_to_crate_id.get(&from_idx) {
|
||||
if let Some((public_deps, libproc_macro)) = &sysroot_deps {
|
||||
public_deps.add_to_crate_graph(crate_graph, from);
|
||||
if let Some(proc_macro) = libproc_macro {
|
||||
add_proc_macro_dep(crate_graph, from, *proc_macro, krate.is_proc_macro);
|
||||
}
|
||||
public_deps.add_to_crate_graph(crate_graph, from);
|
||||
if let Some(proc_macro) = libproc_macro {
|
||||
add_proc_macro_dep(crate_graph, from, proc_macro, krate.is_proc_macro);
|
||||
}
|
||||
|
||||
for dep in &krate.deps {
|
||||
|
@ -999,7 +944,7 @@ fn cargo_to_crate_graph(
|
|||
load: FileLoader<'_>,
|
||||
rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||
cargo: &CargoWorkspace,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
override_cfg: &CfgOverrides,
|
||||
build_scripts: &WorkspaceBuildScripts,
|
||||
|
@ -1008,10 +953,8 @@ fn cargo_to_crate_graph(
|
|||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||
let crate_graph = &mut res.0;
|
||||
let proc_macros = &mut res.1;
|
||||
let (public_deps, libproc_macro) = match sysroot {
|
||||
Some(sysroot) => sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load),
|
||||
None => (SysrootPublicDeps::default(), None),
|
||||
};
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
|
||||
let cfg_options = CfgOptions::from_iter(rustc_cfg);
|
||||
|
||||
|
@ -1188,15 +1131,13 @@ fn detached_file_to_crate_graph(
|
|||
rustc_cfg: Vec<CfgFlag>,
|
||||
load: FileLoader<'_>,
|
||||
detached_file: &ManifestPath,
|
||||
sysroot: Option<&Sysroot>,
|
||||
sysroot: &Sysroot,
|
||||
override_cfg: &CfgOverrides,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "detached_file_to_crate_graph").entered();
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
let (public_deps, _libproc_macro) = match sysroot {
|
||||
Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load),
|
||||
None => (SysrootPublicDeps::default(), None),
|
||||
};
|
||||
let (public_deps, _libproc_macro) =
|
||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
|
||||
let mut cfg_options = CfgOptions::from_iter(rustc_cfg);
|
||||
cfg_options.insert_atom("test".into());
|
||||
|
@ -1431,7 +1372,7 @@ fn sysroot_to_crate_graph(
|
|||
load,
|
||||
None,
|
||||
cargo,
|
||||
None,
|
||||
&Sysroot::empty(),
|
||||
rustc_cfg,
|
||||
&CfgOverrides {
|
||||
global: CfgDiff::new(
|
||||
|
@ -1554,6 +1495,7 @@ fn sysroot_to_crate_graph(
|
|||
stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
|
||||
(public_deps, libproc_macro)
|
||||
}
|
||||
SysrootMode::Empty => (SysrootPublicDeps { deps: vec![] }, None),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,11 +69,9 @@ impl Tester {
|
|||
let cargo_config =
|
||||
CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
|
||||
|
||||
let sysroot =
|
||||
Ok(Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false)
|
||||
.unwrap());
|
||||
let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false);
|
||||
let data_layout = target_data_layout::get(
|
||||
RustcDataLayoutConfig::Rustc(sysroot.as_ref().ok()),
|
||||
RustcDataLayoutConfig::Rustc(&sysroot),
|
||||
None,
|
||||
&cargo_config.extra_env,
|
||||
);
|
||||
|
|
|
@ -1783,18 +1783,18 @@ pub(crate) fn handle_open_docs(
|
|||
let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind {
|
||||
ProjectWorkspaceKind::Cargo { cargo, .. }
|
||||
| ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => {
|
||||
Some((cargo, ws.sysroot.as_ref().ok()))
|
||||
Some((cargo, &ws.sysroot))
|
||||
}
|
||||
ProjectWorkspaceKind::Json { .. } => None,
|
||||
ProjectWorkspaceKind::DetachedFile { .. } => None,
|
||||
});
|
||||
|
||||
let (cargo, sysroot) = match ws_and_sysroot {
|
||||
Some((ws, sysroot)) => (Some(ws), sysroot),
|
||||
Some((ws, sysroot)) => (Some(ws), Some(sysroot)),
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
let sysroot = sysroot.map(|p| p.root().as_str());
|
||||
let sysroot = sysroot.and_then(|p| p.root()).map(|it| it.as_str());
|
||||
let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_str());
|
||||
|
||||
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else {
|
||||
|
|
|
@ -500,7 +500,6 @@ pub struct ServerStatusParams {
|
|||
pub health: Health,
|
||||
pub quiescent: bool,
|
||||
pub message: Option<String>,
|
||||
pub workspace_info: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
|
@ -103,7 +103,6 @@ impl GlobalState {
|
|||
health: lsp_ext::Health::Ok,
|
||||
quiescent: self.is_quiescent(),
|
||||
message: None,
|
||||
workspace_info: None,
|
||||
};
|
||||
let mut message = String::new();
|
||||
|
||||
|
@ -164,53 +163,37 @@ impl GlobalState {
|
|||
let proc_macro_clients =
|
||||
self.proc_macro_clients.iter().map(Some).chain(iter::repeat_with(|| None));
|
||||
|
||||
let mut workspace_info = "Loaded workspaces:\n".to_owned();
|
||||
for (ws, proc_macro_client) in self.workspaces.iter().zip(proc_macro_clients) {
|
||||
format_to!(workspace_info, "- `{}`\n", ws.manifest_or_root());
|
||||
format_to!(workspace_info, " - sysroot:");
|
||||
|
||||
match ws.sysroot.as_ref() {
|
||||
Err(None) => format_to!(workspace_info, " None"),
|
||||
Err(Some(e)) => {
|
||||
status.health |= lsp_ext::Health::Warning;
|
||||
format_to!(workspace_info, " {e}");
|
||||
}
|
||||
Ok(s) => {
|
||||
format_to!(workspace_info, " `{}`", s.root().to_string());
|
||||
if let Some(err) = s
|
||||
.check_has_core()
|
||||
.err()
|
||||
.inspect(|_| status.health |= lsp_ext::Health::Warning)
|
||||
{
|
||||
format_to!(workspace_info, " ({err})");
|
||||
}
|
||||
if let Some(src_root) = s.src_root() {
|
||||
format_to!(
|
||||
workspace_info,
|
||||
"\n - sysroot source: `{}`",
|
||||
src_root
|
||||
);
|
||||
}
|
||||
format_to!(workspace_info, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(e)), .. } = &ws.kind {
|
||||
if let Some(err) = ws.sysroot.error() {
|
||||
status.health |= lsp_ext::Health::Warning;
|
||||
format_to!(workspace_info, " - rustc workspace: {e}\n");
|
||||
format_to!(
|
||||
message,
|
||||
"Workspace `{}` has sysroot errors: ",
|
||||
ws.manifest_or_root()
|
||||
);
|
||||
message.push_str(err);
|
||||
message.push_str("\n\n");
|
||||
}
|
||||
if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(err)), .. } = &ws.kind {
|
||||
status.health |= lsp_ext::Health::Warning;
|
||||
format_to!(
|
||||
message,
|
||||
"Failed loading rustc_private crates for workspace `{}`: ",
|
||||
ws.manifest_or_root()
|
||||
);
|
||||
message.push_str(err);
|
||||
message.push_str("\n\n");
|
||||
};
|
||||
if let Some(proc_macro_client) = proc_macro_client {
|
||||
format_to!(workspace_info, " - proc-macro server: ");
|
||||
match proc_macro_client {
|
||||
Ok(it) => format_to!(workspace_info, "`{}`\n", it.path()),
|
||||
Err(e) => {
|
||||
status.health |= lsp_ext::Health::Warning;
|
||||
format_to!(workspace_info, "{e}\n")
|
||||
}
|
||||
}
|
||||
if let Some(Err(err)) = proc_macro_client {
|
||||
status.health |= lsp_ext::Health::Warning;
|
||||
format_to!(
|
||||
message,
|
||||
"Failed spawning proc-macro server for workspace `{}`: {err}",
|
||||
ws.manifest_or_root()
|
||||
);
|
||||
message.push_str("\n\n");
|
||||
}
|
||||
}
|
||||
status.workspace_info = Some(workspace_info);
|
||||
}
|
||||
|
||||
if !message.is_empty() {
|
||||
|
@ -534,8 +517,8 @@ impl GlobalState {
|
|||
.map(|(a, b)| (a.clone(), b.clone()))
|
||||
.chain(
|
||||
ws.sysroot
|
||||
.as_ref()
|
||||
.map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.root().to_string())),
|
||||
.root()
|
||||
.map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.to_string())),
|
||||
)
|
||||
.collect(),
|
||||
|
||||
|
@ -719,7 +702,7 @@ impl GlobalState {
|
|||
}
|
||||
ProjectWorkspaceKind::DetachedFile { .. } => return None,
|
||||
},
|
||||
ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()),
|
||||
ws.sysroot.root().map(ToOwned::to_owned),
|
||||
))
|
||||
})
|
||||
.map(|(id, (root, manifest_path), sysroot_root)| {
|
||||
|
|
|
@ -21,7 +21,7 @@ fn load_cargo_with_fake_sysroot(file: &str) -> ProjectWorkspace {
|
|||
rustc: Err(None),
|
||||
cargo_config_extra_env: Default::default(),
|
||||
},
|
||||
sysroot: Ok(get_fake_sysroot()),
|
||||
sysroot: get_fake_sysroot(),
|
||||
rustc_cfg: Vec::new(),
|
||||
cfg_overrides: Default::default(),
|
||||
toolchain: None,
|
||||
|
@ -69,7 +69,7 @@ fn get_fake_sysroot() -> Sysroot {
|
|||
// fake sysroot, so we give them both the same path:
|
||||
let sysroot_dir = AbsPathBuf::assert_utf8(sysroot_path);
|
||||
let sysroot_src_dir = sysroot_dir.clone();
|
||||
Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false)
|
||||
Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1059,11 +1059,11 @@ fn resolve_proc_macro() {
|
|||
return;
|
||||
}
|
||||
|
||||
let sysroot = project_model::Sysroot::discover_no_source(
|
||||
let sysroot = project_model::Sysroot::discover(
|
||||
&AbsPathBuf::assert_utf8(std::env::current_dir().unwrap()),
|
||||
&Default::default(),
|
||||
)
|
||||
.unwrap();
|
||||
false,
|
||||
);
|
||||
|
||||
let proc_macro_server_path = sysroot.discover_proc_macro_srv().unwrap();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!---
|
||||
lsp/ext.rs hash: a39009c351009d16
|
||||
lsp/ext.rs hash: 422dcc22c2e56166
|
||||
|
||||
If you need to change the above hash to make the test pass, please check if you
|
||||
need to adjust this doc as well and ping this issue:
|
||||
|
|
|
@ -472,12 +472,6 @@ export class Ctx implements RustAnalyzerExtensionApi {
|
|||
if (status.message) {
|
||||
statusBar.tooltip.appendText(status.message);
|
||||
}
|
||||
if (status.workspaceInfo) {
|
||||
if (statusBar.tooltip.value) {
|
||||
statusBar.tooltip.appendMarkdown("\n\n---\n\n");
|
||||
}
|
||||
statusBar.tooltip.appendMarkdown(status.workspaceInfo);
|
||||
}
|
||||
if (statusBar.tooltip.value) {
|
||||
statusBar.tooltip.appendMarkdown("\n\n---\n\n");
|
||||
}
|
||||
|
|
|
@ -241,7 +241,6 @@ export type ServerStatusParams = {
|
|||
health: "ok" | "warning" | "error";
|
||||
quiescent: boolean;
|
||||
message?: string;
|
||||
workspaceInfo?: string;
|
||||
};
|
||||
export type SsrParams = {
|
||||
query: string;
|
||||
|
|
Loading…
Reference in a new issue