mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-27 02:06:57 +00:00
Re-add rust-analyzer.cargo.sysrootQueryMetadata
This commit is contained in:
parent
ba56d9b9b5
commit
3c98b98ca7
12 changed files with 150 additions and 51 deletions
|
|
@ -13,7 +13,7 @@ use serde_json::from_value;
|
|||
use span::Edition;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::{utf8_stdout, ManifestPath, Sysroot};
|
||||
use crate::{utf8_stdout, ManifestPath, Sysroot, SysrootQueryMetadata};
|
||||
use crate::{CfgOverrides, InvocationStrategy};
|
||||
|
||||
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
|
||||
|
|
@ -85,6 +85,8 @@ pub struct CargoConfig {
|
|||
pub target: Option<String>,
|
||||
/// Sysroot loading behavior
|
||||
pub sysroot: Option<RustLibSource>,
|
||||
/// How to query metadata for the sysroot crate.
|
||||
pub sysroot_query_metadata: SysrootQueryMetadata,
|
||||
pub sysroot_src: Option<AbsPathBuf>,
|
||||
/// rustc private crate source
|
||||
pub rustc_source: Option<RustLibSource>,
|
||||
|
|
|
|||
|
|
@ -240,3 +240,10 @@ fn parse_cfg(s: &str) -> Result<cfg::CfgAtom, String> {
|
|||
};
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub enum SysrootQueryMetadata {
|
||||
#[default]
|
||||
CargoMetadata,
|
||||
None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
|||
use rustc_hash::FxHashMap;
|
||||
use toolchain::{probe_for_binary, Tool};
|
||||
|
||||
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath};
|
||||
use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, SysrootQueryMetadata};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Sysroot {
|
||||
|
|
@ -123,27 +123,43 @@ impl Sysroot {
|
|||
// FIXME: Expose a builder api as loading the sysroot got way too modular and complicated.
|
||||
impl Sysroot {
|
||||
/// Attempts to discover the toolchain's sysroot from the given `dir`.
|
||||
pub fn discover(dir: &AbsPath, extra_env: &FxHashMap<String, String>) -> Sysroot {
|
||||
pub fn discover(
|
||||
dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> 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)
|
||||
Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir, sysroot_query_metadata)
|
||||
}
|
||||
|
||||
pub fn discover_with_src_override(
|
||||
current_dir: &AbsPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot_src_dir: AbsPathBuf,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> Sysroot {
|
||||
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env);
|
||||
Sysroot::load_core_check(Some(sysroot_dir), Some(Ok(sysroot_src_dir)))
|
||||
Sysroot::load_core_check(
|
||||
Some(sysroot_dir),
|
||||
Some(Ok(sysroot_src_dir)),
|
||||
sysroot_query_metadata,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn discover_sysroot_src_dir(sysroot_dir: AbsPathBuf) -> Sysroot {
|
||||
pub fn discover_sysroot_src_dir(
|
||||
sysroot_dir: AbsPathBuf,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> 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))
|
||||
Sysroot::load_core_check(
|
||||
Some(Ok(sysroot_dir)),
|
||||
Some(sysroot_src_dir),
|
||||
sysroot_query_metadata,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn discover_rustc_src(&self) -> Option<ManifestPath> {
|
||||
|
|
@ -186,15 +202,20 @@ impl Sysroot {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn load(sysroot_dir: Option<AbsPathBuf>, sysroot_src_dir: Option<AbsPathBuf>) -> Sysroot {
|
||||
Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok))
|
||||
pub fn load(
|
||||
sysroot_dir: Option<AbsPathBuf>,
|
||||
sysroot_src_dir: Option<AbsPathBuf>,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> Sysroot {
|
||||
Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), sysroot_query_metadata)
|
||||
}
|
||||
|
||||
fn load_core_check(
|
||||
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> Sysroot {
|
||||
let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir);
|
||||
let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, sysroot_query_metadata);
|
||||
if sysroot.error.is_none() {
|
||||
if let Some(src_root) = &sysroot.src_root {
|
||||
let has_core = match &sysroot.mode {
|
||||
|
|
@ -220,6 +241,7 @@ impl Sysroot {
|
|||
fn load_(
|
||||
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
|
||||
sysroot_query_metadata: SysrootQueryMetadata,
|
||||
) -> Sysroot {
|
||||
let sysroot_dir = match sysroot_dir {
|
||||
Some(Ok(sysroot_dir)) => Some(sysroot_dir),
|
||||
|
|
@ -252,12 +274,15 @@ impl Sysroot {
|
|||
}
|
||||
}
|
||||
};
|
||||
let library_manifest = ManifestPath::try_from(sysroot_src_dir.join("Cargo.toml")).unwrap();
|
||||
if fs::metadata(&library_manifest).is_ok() {
|
||||
if let Some(sysroot) =
|
||||
Self::load_library_via_cargo(library_manifest, &sysroot_dir, &sysroot_src_dir)
|
||||
{
|
||||
return sysroot;
|
||||
if sysroot_query_metadata == SysrootQueryMetadata::CargoMetadata {
|
||||
let library_manifest =
|
||||
ManifestPath::try_from(sysroot_src_dir.join("Cargo.toml")).unwrap();
|
||||
if fs::metadata(&library_manifest).is_ok() {
|
||||
if let Some(sysroot) =
|
||||
Self::load_library_via_cargo(library_manifest, &sysroot_dir, &sysroot_src_dir)
|
||||
{
|
||||
return sysroot;
|
||||
}
|
||||
}
|
||||
}
|
||||
tracing::debug!("Stitching sysroot library: {sysroot_src_dir}");
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
sysroot::SysrootMode, workspace::ProjectWorkspaceKind, CargoWorkspace, CfgOverrides,
|
||||
ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot, WorkspaceBuildScripts,
|
||||
ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot, SysrootQueryMetadata,
|
||||
WorkspaceBuildScripts,
|
||||
};
|
||||
|
||||
fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
||||
|
|
@ -116,7 +117,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(Some(sysroot_dir), Some(sysroot_src_dir))
|
||||
Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), SysrootQueryMetadata::CargoMetadata)
|
||||
}
|
||||
|
||||
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
||||
|
|
@ -231,6 +232,7 @@ fn smoke_test_real_sysroot_cargo() {
|
|||
let sysroot = Sysroot::discover(
|
||||
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
|
||||
&Default::default(),
|
||||
SysrootQueryMetadata::CargoMetadata,
|
||||
);
|
||||
assert!(matches!(sysroot.mode(), SysrootMode::Workspace(_)));
|
||||
let project_workspace = ProjectWorkspace {
|
||||
|
|
|
|||
|
|
@ -211,34 +211,35 @@ impl ProjectWorkspace {
|
|||
let project_location = project_json.parent().to_path_buf();
|
||||
let project_json: ProjectJson =
|
||||
ProjectJson::new(Some(project_json.clone()), &project_location, data);
|
||||
ProjectWorkspace::load_inline(
|
||||
project_json,
|
||||
config.target.as_deref(),
|
||||
&config.extra_env,
|
||||
&config.cfg_overrides,
|
||||
)
|
||||
ProjectWorkspace::load_inline(project_json, config)
|
||||
}
|
||||
ProjectManifest::CargoScript(rust_file) => {
|
||||
ProjectWorkspace::load_detached_file(rust_file, config)?
|
||||
}
|
||||
ProjectManifest::CargoToml(cargo_toml) => {
|
||||
let sysroot = match (&config.sysroot, &config.sysroot_src) {
|
||||
(Some(RustLibSource::Discover), None) => {
|
||||
Sysroot::discover(cargo_toml.parent(), &config.extra_env)
|
||||
}
|
||||
(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,
|
||||
)
|
||||
}
|
||||
(Some(RustLibSource::Path(path)), None) => {
|
||||
Sysroot::discover_sysroot_src_dir(path.clone())
|
||||
}
|
||||
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => {
|
||||
Sysroot::load(Some(sysroot.clone()), Some(sysroot_src.clone()))
|
||||
}
|
||||
(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(),
|
||||
};
|
||||
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
|
||||
|
|
@ -352,20 +353,19 @@ impl ProjectWorkspace {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn load_inline(
|
||||
project_json: ProjectJson,
|
||||
target: Option<&str>,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
cfg_overrides: &CfgOverrides,
|
||||
) -> ProjectWorkspace {
|
||||
let sysroot = Sysroot::load(project_json.sysroot.clone(), project_json.sysroot_src.clone());
|
||||
pub fn load_inline(project_json: ProjectJson, config: &CargoConfig) -> ProjectWorkspace {
|
||||
let sysroot = Sysroot::load(
|
||||
project_json.sysroot.clone(),
|
||||
project_json.sysroot_src.clone(),
|
||||
config.sysroot_query_metadata,
|
||||
);
|
||||
let cfg_config = RustcCfgConfig::Rustc(&sysroot);
|
||||
let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot);
|
||||
let toolchain = match get_toolchain_version(
|
||||
project_json.path(),
|
||||
&sysroot,
|
||||
Tool::Rustc,
|
||||
extra_env,
|
||||
&config.extra_env,
|
||||
"rustc ",
|
||||
) {
|
||||
Ok(it) => it,
|
||||
|
|
@ -375,15 +375,16 @@ impl ProjectWorkspace {
|
|||
}
|
||||
};
|
||||
|
||||
let rustc_cfg = rustc_cfg::get(target, extra_env, cfg_config);
|
||||
let data_layout = target_data_layout::get(data_layout_config, target, extra_env);
|
||||
let target = config.target.as_deref();
|
||||
let rustc_cfg = rustc_cfg::get(target, &config.extra_env, cfg_config);
|
||||
let data_layout = target_data_layout::get(data_layout_config, target, &config.extra_env);
|
||||
ProjectWorkspace {
|
||||
kind: ProjectWorkspaceKind::Json(project_json),
|
||||
sysroot,
|
||||
rustc_cfg,
|
||||
toolchain,
|
||||
target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())),
|
||||
cfg_overrides: cfg_overrides.clone(),
|
||||
cfg_overrides: config.cfg_overrides.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,8 +394,12 @@ impl ProjectWorkspace {
|
|||
) -> anyhow::Result<ProjectWorkspace> {
|
||||
let dir = detached_file.parent();
|
||||
let sysroot = match &config.sysroot {
|
||||
Some(RustLibSource::Path(path)) => Sysroot::discover_sysroot_src_dir(path.clone()),
|
||||
Some(RustLibSource::Discover) => Sysroot::discover(dir, &config.extra_env),
|
||||
Some(RustLibSource::Path(path)) => {
|
||||
Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata)
|
||||
}
|
||||
Some(RustLibSource::Discover) => {
|
||||
Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata)
|
||||
}
|
||||
None => Sysroot::empty(),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue