Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/project-model/src/build_dependencies.rs | 3 | ||||
| -rw-r--r-- | crates/project-model/src/cargo_config_file.rs | 4 | ||||
| -rw-r--r-- | crates/project-model/src/cargo_workspace.rs | 8 | ||||
| -rw-r--r-- | crates/project-model/src/workspace.rs | 21 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/config.rs | 15 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/flycheck.rs | 5 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/handlers/request.rs | 8 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/target_spec.rs | 4 | ||||
| -rw-r--r-- | docs/book/src/configuration_generated.md | 9 | ||||
| -rw-r--r-- | editors/code/package.json | 13 |
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": [], |