Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add rust-analyzer.cargo.sysrootQueryMetadata #18511

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/project-model/src/cargo_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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>,
Expand Down
7 changes: 7 additions & 0 deletions crates/project-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
55 changes: 40 additions & 15 deletions crates/project-model/src/sysroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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 {
Expand All @@ -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),
Expand Down Expand Up @@ -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}");
Expand Down
6 changes: 4 additions & 2 deletions crates/project-model/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
61 changes: 33 additions & 28 deletions crates/project-model/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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,
Expand All @@ -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(),
}
}

Expand All @@ -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(),
};

Expand Down
4 changes: 4 additions & 0 deletions crates/rust-analyzer/src/cli/analysis_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ impl flags::AnalysisStats {
true => None,
false => Some(RustLibSource::Discover),
},
sysroot_query_metadata: match self.no_query_sysroot_metadata {
true => project_model::SysrootQueryMetadata::None,
false => project_model::SysrootQueryMetadata::CargoMetadata,
},
all_targets: true,
set_test: !self.no_test,
cfg_overrides: CfgOverrides {
Expand Down
4 changes: 4 additions & 0 deletions crates/rust-analyzer/src/cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ xflags::xflags! {
optional --with-deps
/// Don't load sysroot crates (`std`, `core` & friends).
optional --no-sysroot
/// Don't run cargo metadata on the sysroot to analyze its third-party dependencies.
/// Requires --no-sysroot to not be set.
optional --no-query-sysroot-metadata
/// Don't set #[cfg(test)].
optional --no-test

Expand Down Expand Up @@ -235,6 +238,7 @@ pub struct AnalysisStats {
pub only: Option<String>,
pub with_deps: bool,
pub no_sysroot: bool,
pub no_query_sysroot_metadata: bool,
pub no_test: bool,
pub disable_build_scripts: bool,
pub disable_proc_macros: bool,
Expand Down
8 changes: 6 additions & 2 deletions crates/rust-analyzer/src/cli/rustc_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use profile::StopWatch;
use project_model::target_data_layout::RustcDataLayoutConfig;
use project_model::{
target_data_layout, CargoConfig, ManifestPath, ProjectWorkspace, ProjectWorkspaceKind,
RustLibSource, Sysroot,
RustLibSource, Sysroot, SysrootQueryMetadata,
};

use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice};
Expand Down Expand Up @@ -74,7 +74,11 @@ impl Tester {
..Default::default()
};

let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env);
let sysroot = Sysroot::discover(
tmp_file.parent().unwrap(),
&cargo_config.extra_env,
SysrootQueryMetadata::CargoMetadata,
);
let data_layout = target_data_layout::get(
RustcDataLayoutConfig::Rustc(&sysroot),
None,
Expand Down
24 changes: 24 additions & 0 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,9 @@ config_data! {
///
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysroot: Option<String> = Some("discover".to_owned()),
/// How to query metadata for the sysroot crate. Using cargo metadata allows rust-analyzer
/// to analyze third-party dependencies of the standard libraries.
cargo_sysrootQueryMetadata: SysrootQueryMetadata = SysrootQueryMetadata::CargoMetadata,
/// Relative path to the sysroot library sources. If left unset, this will default to
/// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
///
Expand Down Expand Up @@ -1868,6 +1871,12 @@ impl Config {
},
target: self.cargo_target(source_root).clone(),
sysroot,
sysroot_query_metadata: match self.cargo_sysrootQueryMetadata(None) {
SysrootQueryMetadata::CargoMetadata => {
project_model::SysrootQueryMetadata::CargoMetadata
}
SysrootQueryMetadata::None => project_model::SysrootQueryMetadata::None,
},
sysroot_src,
rustc_source,
cfg_overrides: project_model::CfgOverrides {
Expand Down Expand Up @@ -2559,6 +2568,13 @@ pub enum NumThreads {
Concrete(usize),
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SysrootQueryMetadata {
CargoMetadata,
None,
}

macro_rules! _default_val {
(@verbatim: $s:literal, $ty:ty) => {{
let default_: $ty = serde_json::from_str(&$s).unwrap();
Expand Down Expand Up @@ -3410,6 +3426,14 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
}
]
},
"SysrootQueryMetadata" => set! {
"type": "string",
"enum": ["none", "cargo_metadata"],
"enumDescriptions": [
"Do not query sysroot metadata, always use stitched sysroot.",
"Use `cargo metadata` to query sysroot metadata."
],
},
_ => panic!("missing entry for {ty}: {default} (field {field})"),
}

Expand Down
4 changes: 1 addition & 3 deletions crates/rust-analyzer/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,7 @@ impl GlobalState {
LinkedProject::InlineJsonProject(it) => {
let workspace = project_model::ProjectWorkspace::load_inline(
it.clone(),
cargo_config.target.as_deref(),
&cargo_config.extra_env,
&cargo_config.cfg_overrides,
&cargo_config,
);
Ok(workspace)
}
Expand Down
Loading