Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22679 from emilio/cargo-configPath
project-model: Introduce cargo.configPath
Chayim Refael Friedman 2 weeks ago
parent e47d755 · parent daddd89 · commit cc5f0f8
-rw-r--r--crates/project-model/src/build_dependencies.rs3
-rw-r--r--crates/project-model/src/cargo_config_file.rs4
-rw-r--r--crates/project-model/src/cargo_workspace.rs8
-rw-r--r--crates/project-model/src/workspace.rs21
-rw-r--r--crates/rust-analyzer/src/config.rs15
-rw-r--r--crates/rust-analyzer/src/flycheck.rs5
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs8
-rw-r--r--crates/rust-analyzer/src/target_spec.rs4
-rw-r--r--docs/book/src/configuration_generated.md9
-rw-r--r--editors/code/package.json13
10 files changed, 88 insertions, 2 deletions
diff --git a/crates/project-model/src/build_dependencies.rs b/crates/project-model/src/build_dependencies.rs
index 352f41a826..336350653b 100644
--- a/crates/project-model/src/build_dependencies.rs
+++ b/crates/project-model/src/build_dependencies.rs
@@ -450,6 +450,9 @@ impl WorkspaceBuildScripts {
cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]);
cmd.args(&config.extra_args);
+ if let Some(config_path) = &config.config_path {
+ cmd.arg("--config").arg(config_path);
+ }
cmd.arg("--manifest-path");
cmd.arg(manifest_path);
diff --git a/crates/project-model/src/cargo_config_file.rs b/crates/project-model/src/cargo_config_file.rs
index ae36deb71f..39d1a82518 100644
--- a/crates/project-model/src/cargo_config_file.rs
+++ b/crates/project-model/src/cargo_config_file.rs
@@ -17,11 +17,15 @@ impl CargoConfigFile {
manifest: &ManifestPath,
extra_env: &FxHashMap<String, Option<String>>,
sysroot: &Sysroot,
+ config_path: Option<&AbsPath>,
) -> Option<Self> {
let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
cargo_config
.args(["-Z", "unstable-options", "config", "get", "--format", "toml", "--show-origin"])
.env("RUSTC_BOOTSTRAP", "1");
+ if let Some(config_path) = config_path {
+ cargo_config.arg("--config").arg(config_path);
+ }
if manifest.is_rust_manifest() {
cargo_config.arg("-Zscript");
}
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index 5d8273832b..004d62967a 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -133,6 +133,8 @@ pub struct CargoConfig {
pub extra_args: Vec<String>,
/// Extra args passed only to `cargo metadata`, not other cargo commands.
pub metadata_extra_args: Vec<String>,
+ /// Path to an extra config file passed to every cargo invocation via `--config`.
+ pub config_path: Option<AbsPathBuf>,
/// Extra env vars to set when invoking the cargo command
pub extra_env: FxHashMap<String, Option<String>>,
pub invocation_strategy: InvocationStrategy,
@@ -324,6 +326,8 @@ pub struct CargoMetadataConfig {
pub extra_args: Vec<String>,
/// Extra args passed directly to `cargo metadata` without filtering.
pub metadata_extra_args: Vec<String>,
+ /// Path to an extra config file passed to `cargo metadata` via `--config`.
+ pub config_path: Option<AbsPathBuf>,
/// Extra env vars to set when invoking the cargo command
pub extra_env: FxHashMap<String, Option<String>>,
/// What kind of metadata are we fetching: workspace, rustc, or sysroot.
@@ -684,6 +688,10 @@ impl FetchMetadata {
}
}
other_options.extend(config.metadata_extra_args.iter().cloned());
+ if let Some(config_path) = &config.config_path {
+ other_options.push("--config".to_owned());
+ other_options.push(config_path.to_string());
+ }
let mut lockfile_copy = None;
if cargo_toml.is_rust_manifest() {
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 784255ff05..9002b0c3bb 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -217,6 +217,7 @@ impl ProjectWorkspace {
rustc_source,
extra_args,
metadata_extra_args,
+ config_path,
extra_env,
set_test,
cfg_overrides,
@@ -269,7 +270,8 @@ impl ProjectWorkspace {
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.rust_lib_src_root(), root = ?sysroot.root(), "Using sysroot");
progress("querying project metadata".to_owned());
- let config_file = CargoConfigFile::load(cargo_toml, extra_env, &sysroot);
+ let config_file =
+ CargoConfigFile::load(cargo_toml, extra_env, &sysroot, config_path.as_deref());
let config_file_ = config_file.clone();
let toolchain_config = QueryConfig::Cargo(&sysroot, cargo_toml, &config_file_);
let targets =
@@ -291,6 +293,7 @@ impl ProjectWorkspace {
targets: targets.clone(),
extra_args: extra_args.clone(),
metadata_extra_args: metadata_extra_args.clone(),
+ config_path: config_path.clone(),
extra_env: extra_env.clone(),
toolchain_version: toolchain.clone(),
kind: "workspace",
@@ -346,6 +349,7 @@ impl ProjectWorkspace {
targets: targets.clone(),
extra_args: extra_args.clone(),
metadata_extra_args: metadata_extra_args.clone(),
+ config_path: config_path.clone(),
extra_env: extra_env.clone(),
toolchain_version: toolchain.clone(),
kind: "rustc-dev"
@@ -549,7 +553,12 @@ impl ProjectWorkspace {
None => Sysroot::empty(),
};
- let config_file = CargoConfigFile::load(detached_file, &config.extra_env, &sysroot);
+ let config_file = CargoConfigFile::load(
+ detached_file,
+ &config.extra_env,
+ &sysroot,
+ config.config_path.as_deref(),
+ );
let query_config = QueryConfig::Cargo(&sysroot, detached_file, &config_file);
let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
@@ -579,6 +588,7 @@ impl ProjectWorkspace {
targets,
extra_args: config.extra_args.clone(),
metadata_extra_args: config.metadata_extra_args.clone(),
+ config_path: config.config_path.clone(),
extra_env: config.extra_env.clone(),
toolchain_version: toolchain.clone(),
kind: "detached-file",
@@ -1952,8 +1962,15 @@ fn sysroot_metadata_config(
CargoMetadataConfig {
features: Default::default(),
targets,
+ // NOTE: Not passing extra_args / metadata_extra_args / config_path here is very
+ // intentional. The sysroot config has nothing to do with the workspace's config, so it's
+ // very unlikely to do the right thing (e.g. it'd could try to use vendored dependencies in
+ // the project's config for libstd or what not).
extra_args: Default::default(),
metadata_extra_args: Default::default(),
+ config_path: Default::default(),
+ // FIXME: Passing extra_env is somewhat dubious here, for the same reason we don't pass
+ // extra_args.
extra_env: config.extra_env.clone(),
toolchain_version,
kind: "sysroot",
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 5fc17a52b9..552fb079c2 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -833,6 +833,10 @@ config_data! {
cargo_cfgs: Vec<String> = {
vec!["debug_assertions".into(), "miri".into()]
},
+ /// Path to a `.cargo/config.toml` style file to pass to cargo via `--config`
+ /// for every cargo invocation (metadata, build scripts, config discovery).
+ /// Useful to give rust-analyzer a consistent view of the project configuration.
+ cargo_configPath: Option<Utf8PathBuf> = None,
/// Extra arguments that are passed to every cargo invocation.
cargo_extraArgs: Vec<String> = vec![],
/// Extra environment variables that will be set when running cargo, rustc
@@ -1684,6 +1688,8 @@ pub struct RunnablesConfig {
pub override_cargo: Option<String>,
/// Additional arguments for the `cargo`, e.g. `--release`.
pub cargo_extra_args: Vec<String>,
+ /// Path to an extra config file passed to cargo via `--config`.
+ pub config_path: Option<AbsPathBuf>,
/// Additional arguments for the binary being run, if it is a test or benchmark.
pub extra_test_binary_args: Vec<String>,
/// Subcommand used for doctest runnables instead of `test`.
@@ -2418,6 +2424,7 @@ impl Config {
});
let sysroot_src =
self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot));
+ let config_path = self.cargo_config_path(source_root);
let extra_includes = self
.vfs_extraIncludes(source_root)
.iter()
@@ -2484,6 +2491,7 @@ impl Config {
set_test: *self.cfg_setTest(source_root),
no_deps: *self.cargo_noDeps(source_root),
metadata_extra_args: self.cargo_metadataExtraArgs(source_root).clone(),
+ config_path,
}
}
@@ -2573,6 +2581,7 @@ impl Config {
extra_env: self.extra_env(source_root).clone(),
target_dir_config: self.target_dir_from_config(source_root),
set_test: true,
+ config_path: self.cargo_config_path(source_root),
}
}
@@ -2629,6 +2638,7 @@ impl Config {
extra_args: self.check_extra_args(source_root),
extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
extra_env: self.check_extra_env(source_root),
+ config_path: self.cargo_config_path(source_root),
target_dir_config: self.target_dir_from_config(source_root),
set_test: *self.cfg_setTest(source_root),
},
@@ -2637,6 +2647,10 @@ impl Config {
}
}
+ fn cargo_config_path(&self, source_root: Option<SourceRootId>) -> Option<AbsPathBuf> {
+ self.cargo_configPath(source_root).as_ref().map(|path| self.root_path.join(path))
+ }
+
fn target_dir_from_config(&self, source_root: Option<SourceRootId>) -> TargetDirectoryConfig {
match &self.cargo_targetDir(source_root) {
Some(TargetDirectory::UseSubdirectory(true)) => TargetDirectoryConfig::UseSubdirectory,
@@ -2657,6 +2671,7 @@ impl Config {
RunnablesConfig {
override_cargo: self.runnables_command(source_root).clone(),
cargo_extra_args: self.runnables_extraArgs(source_root).clone(),
+ config_path: self.cargo_config_path(source_root),
extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
test_command: self.runnables_test_command(source_root).clone(),
test_override_command: self.runnables_test_overrideCommand(source_root).clone(),
diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs
index 3c9a8c147d..16dd9bee1f 100644
--- a/crates/rust-analyzer/src/flycheck.rs
+++ b/crates/rust-analyzer/src/flycheck.rs
@@ -51,6 +51,7 @@ pub(crate) struct CargoOptions {
pub(crate) extra_args: Vec<String>,
pub(crate) extra_test_bin_args: Vec<String>,
pub(crate) extra_env: FxHashMap<String, Option<String>>,
+ pub(crate) config_path: Option<AbsPathBuf>,
pub(crate) target_dir_config: TargetDirectoryConfig,
}
@@ -108,6 +109,9 @@ impl CargoOptions {
cmd.arg(features);
}
}
+ if let Some(config_path) = &self.config_path {
+ cmd.arg("--config").arg(config_path);
+ }
if let Some(target_dir) = self.target_dir_config.target_dir(ws_target_dir) {
cmd.arg("--target-dir").arg(target_dir.as_ref());
}
@@ -1169,6 +1173,7 @@ mod tests {
extra_args: vec![],
extra_test_bin_args: vec![],
extra_env: FxHashMap::default(),
+ config_path: None,
target_dir_config: TargetDirectoryConfig::default(),
},
ansi_color_output: true,
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 9710a19d69..e57b05660d 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -1074,6 +1074,10 @@ pub(crate) fn handle_runnables(
cargo_args.push("--all-targets".to_owned());
}
cargo_args.extend(config.cargo_extra_args.iter().cloned());
+ if let Some(config_path) = &config.config_path {
+ cargo_args.push("--config".to_owned());
+ cargo_args.push(config_path.to_string());
+ }
res.push(lsp_ext::Runnable {
label: format!(
"cargo {cmd} -p {}{all_targets}",
@@ -1104,6 +1108,10 @@ pub(crate) fn handle_runnables(
{
let mut cargo_args = vec!["check".to_owned(), "--workspace".to_owned()];
cargo_args.extend(config.cargo_extra_args.iter().cloned());
+ if let Some(config_path) = &config.config_path {
+ cargo_args.push("--config".to_owned());
+ cargo_args.push(config_path.to_string());
+ }
res.push(lsp_ext::Runnable {
label: "cargo check --workspace".to_owned(),
location: None,
diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs
index fdcd2c98b9..7c957603de 100644
--- a/crates/rust-analyzer/src/target_spec.rs
+++ b/crates/rust-analyzer/src/target_spec.rs
@@ -204,6 +204,10 @@ impl CargoTargetSpec {
}
}
cargo_args.extend(config.cargo_extra_args.iter().cloned());
+ if let Some(config_path) = &config.config_path {
+ cargo_args.push("--config".to_owned());
+ cargo_args.push(config_path.to_string());
+ }
(cargo_args, executable_args)
}
diff --git a/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md
index 76b626b09f..1f94639074 100644
--- a/docs/book/src/configuration_generated.md
+++ b/docs/book/src/configuration_generated.md
@@ -142,6 +142,15 @@ To enable a name with a value, use `"key=value"`.
To disable, prefix the entry with a `!`.
+## rust-analyzer.cargo.configPath {#cargo.configPath}
+
+Default: `null`
+
+Path to a `.cargo/config.toml` style file to pass to cargo via `--config`
+for every cargo invocation (metadata, build scripts, config discovery).
+Useful to give rust-analyzer a consistent view of the project configuration.
+
+
## rust-analyzer.cargo.extraArgs {#cargo.extraArgs}
Default: `[]`
diff --git a/editors/code/package.json b/editors/code/package.json
index 7380ebad2b..c9ab57be99 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -974,6 +974,19 @@
{
"title": "Cargo",
"properties": {
+ "rust-analyzer.cargo.configPath": {
+ "markdownDescription": "Path to a `.cargo/config.toml` style file to pass to cargo via `--config`\nfor every cargo invocation (metadata, build scripts, config discovery).\nUseful to give rust-analyzer a consistent view of the project configuration.",
+ "default": null,
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ }
+ },
+ {
+ "title": "Cargo",
+ "properties": {
"rust-analyzer.cargo.extraArgs": {
"markdownDescription": "Extra arguments that are passed to every cargo invocation.",
"default": [],