Make cargo_ workspace again

This commit is contained in:
Ali Bektas 2024-08-22 19:03:00 +02:00
parent f454ea8771
commit 100d3f9c06
8 changed files with 190 additions and 157 deletions

View file

@ -51,7 +51,7 @@ impl flags::Scip {
// FIXME @alibektas : What happens to errors without logging? // FIXME @alibektas : What happens to errors without logging?
error!(?error_sink, "Config Error(s)"); error!(?error_sink, "Config Error(s)");
} }
let cargo_config = config.cargo(); let cargo_config = config.cargo(None);
let (db, vfs, _) = load_workspace_at( let (db, vfs, _) = load_workspace_at(
root.as_path().as_ref(), root.as_path().as_ref(),
&cargo_config, &cargo_config,

View file

@ -76,87 +76,6 @@ config_data! {
/// How many worker threads to handle priming caches. The default `0` means to pick automatically. /// How many worker threads to handle priming caches. The default `0` means to pick automatically.
cachePriming_numThreads: NumThreads = NumThreads::Physical, cachePriming_numThreads: NumThreads = NumThreads::Physical,
/// Pass `--all-targets` to cargo invocation.
cargo_allTargets: bool = true,
/// Automatically refresh project info via `cargo metadata` on
/// `Cargo.toml` or `.cargo/config.toml` changes.
pub(crate) cargo_autoreload: bool = true,
/// Run build scripts (`build.rs`) for more precise code analysis.
cargo_buildScripts_enable: bool = true,
/// Specifies the invocation strategy to use when running the build scripts command.
/// If `per_workspace` is set, the command will be executed for each Rust workspace with the
/// workspace as the working directory.
/// If `once` is set, the command will be executed once with the opened project as the
/// working directory.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set.
cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
/// Override the command rust-analyzer uses to run build scripts and
/// build procedural macros. The command is required to output json
/// and should therefore include `--message-format=json` or a similar
/// option.
///
/// If there are multiple linked projects/workspaces, this command is invoked for
/// each of them, with the working directory being the workspace root
/// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
/// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
///
/// By default, a cargo invocation will be constructed for the configured
/// targets and features, with the following base command line:
///
/// ```bash
/// cargo check --quiet --workspace --message-format=json --all-targets --keep-going
/// ```
/// .
cargo_buildScripts_overrideCommand: Option<Vec<String>> = None,
/// Rerun proc-macros building/build-scripts running when proc-macro
/// or build-script sources change and are saved.
cargo_buildScripts_rebuildOnSave: bool = true,
/// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
/// avoid checking unnecessary things.
cargo_buildScripts_useRustcWrapper: bool = true,
/// List of cfg options to enable with the given values.
cargo_cfgs: FxHashMap<String, Option<String>> = {
let mut m = FxHashMap::default();
m.insert("debug_assertions".to_owned(), None);
m.insert("miri".to_owned(), None);
m
},
/// 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
/// or other commands within the workspace. Useful for setting RUSTFLAGS.
cargo_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
/// List of features to activate.
///
/// Set this to `"all"` to pass `--all-features` to cargo.
cargo_features: CargoFeaturesDef = CargoFeaturesDef::Selected(vec![]),
/// Whether to pass `--no-default-features` to cargo.
cargo_noDefaultFeatures: bool = false,
/// Relative path to the sysroot, or "discover" to try to automatically find it via
/// "rustc --print sysroot".
///
/// Unsetting this disables sysroot loading.
///
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysroot: Option<String> = Some("discover".to_owned()),
/// Relative path to the sysroot library sources. If left unset, this will default to
/// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
///
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysrootSrc: Option<String> = None,
/// Compilation target override (target triple).
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
// than `checkOnSave_target`
cargo_target: Option<String> = None,
/// Optional path to a rust-analyzer specific target directory.
/// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
/// building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
///
/// Set to `true` to use a subdirectory of the existing target directory or
/// set to a path relative to the workspace to use that path.
cargo_targetDir | rust_analyzerTargetDir: Option<TargetDirectory> = None,
/// Run the check command for diagnostics on save. /// Run the check command for diagnostics on save.
checkOnSave | checkOnSave_enable: bool = true, checkOnSave | checkOnSave_enable: bool = true,
@ -430,6 +349,88 @@ config_data! {
config_data! { config_data! {
workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> { workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> {
/// Pass `--all-targets` to cargo invocation.
cargo_allTargets: bool = true,
/// Automatically refresh project info via `cargo metadata` on
/// `Cargo.toml` or `.cargo/config.toml` changes.
pub(crate) cargo_autoreload: bool = true,
/// Run build scripts (`build.rs`) for more precise code analysis.
cargo_buildScripts_enable: bool = true,
/// Specifies the invocation strategy to use when running the build scripts command.
/// If `per_workspace` is set, the command will be executed for each Rust workspace with the
/// workspace as the working directory.
/// If `once` is set, the command will be executed once with the opened project as the
/// working directory.
/// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
/// is set.
cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
/// Override the command rust-analyzer uses to run build scripts and
/// build procedural macros. The command is required to output json
/// and should therefore include `--message-format=json` or a similar
/// option.
///
/// If there are multiple linked projects/workspaces, this command is invoked for
/// each of them, with the working directory being the workspace root
/// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
/// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
///
/// By default, a cargo invocation will be constructed for the configured
/// targets and features, with the following base command line:
///
/// ```bash
/// cargo check --quiet --workspace --message-format=json --all-targets --keep-going
/// ```
/// .
cargo_buildScripts_overrideCommand: Option<Vec<String>> = None,
/// Rerun proc-macros building/build-scripts running when proc-macro
/// or build-script sources change and are saved.
cargo_buildScripts_rebuildOnSave: bool = true,
/// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
/// avoid checking unnecessary things.
cargo_buildScripts_useRustcWrapper: bool = true,
/// List of cfg options to enable with the given values.
cargo_cfgs: FxHashMap<String, Option<String>> = {
let mut m = FxHashMap::default();
m.insert("debug_assertions".to_owned(), None);
m.insert("miri".to_owned(), None);
m
},
/// 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
/// or other commands within the workspace. Useful for setting RUSTFLAGS.
cargo_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
/// List of features to activate.
///
/// Set this to `"all"` to pass `--all-features` to cargo.
cargo_features: CargoFeaturesDef = CargoFeaturesDef::Selected(vec![]),
/// Whether to pass `--no-default-features` to cargo.
cargo_noDefaultFeatures: bool = false,
/// Relative path to the sysroot, or "discover" to try to automatically find it via
/// "rustc --print sysroot".
///
/// Unsetting this disables sysroot loading.
///
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysroot: Option<String> = Some("discover".to_owned()),
/// Relative path to the sysroot library sources. If left unset, this will default to
/// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
///
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysrootSrc: Option<String> = None,
/// Compilation target override (target triple).
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
// than `checkOnSave_target`
cargo_target: Option<String> = None,
/// Optional path to a rust-analyzer specific target directory.
/// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
/// building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
///
/// Set to `true` to use a subdirectory of the existing target directory or
/// set to a path relative to the workspace to use that path.
cargo_targetDir | rust_analyzerTargetDir: Option<TargetDirectory> = None,
/// Additional arguments to `rustfmt`. /// Additional arguments to `rustfmt`.
rustfmt_extraArgs: Vec<String> = vec![], rustfmt_extraArgs: Vec<String> = vec![],
/// Advanced option, fully override the command rust-analyzer uses for /// Advanced option, fully override the command rust-analyzer uses for
@ -1728,22 +1729,22 @@ impl Config {
} }
} }
pub fn extra_args(&self) -> &Vec<String> { pub fn extra_args(&self, source_root: Option<SourceRootId>) -> &Vec<String> {
self.cargo_extraArgs() self.cargo_extraArgs(source_root)
} }
pub fn extra_env(&self) -> &FxHashMap<String, String> { pub fn extra_env(&self, source_root: Option<SourceRootId>) -> &FxHashMap<String, String> {
self.cargo_extraEnv() self.cargo_extraEnv(source_root)
} }
pub fn check_extra_args(&self) -> Vec<String> { pub fn check_extra_args(&self, source_root: Option<SourceRootId>) -> Vec<String> {
let mut extra_args = self.extra_args().clone(); let mut extra_args = self.extra_args(source_root).clone();
extra_args.extend_from_slice(self.check_extraArgs()); extra_args.extend_from_slice(self.check_extraArgs());
extra_args extra_args
} }
pub fn check_extra_env(&self) -> FxHashMap<String, String> { pub fn check_extra_env(&self, source_root: Option<SourceRootId>) -> FxHashMap<String, String> {
let mut extra_env = self.cargo_extraEnv().clone(); let mut extra_env = self.cargo_extraEnv(source_root).clone();
extra_env.extend(self.check_extraEnv().clone()); extra_env.extend(self.check_extraEnv().clone());
extra_env extra_env
} }
@ -1787,15 +1788,15 @@ impl Config {
} }
} }
pub fn cargo_autoreload_config(&self) -> bool { pub fn cargo_autoreload_config(&self, source_root: Option<SourceRootId>) -> bool {
self.cargo_autoreload().to_owned() self.cargo_autoreload(source_root).to_owned()
} }
pub fn run_build_scripts(&self) -> bool { pub fn run_build_scripts(&self, source_root: Option<SourceRootId>) -> bool {
self.cargo_buildScripts_enable().to_owned() || self.procMacro_enable().to_owned() self.cargo_buildScripts_enable(source_root).to_owned() || self.procMacro_enable().to_owned()
} }
pub fn cargo(&self) -> CargoConfig { pub fn cargo(&self, source_root: Option<SourceRootId>) -> CargoConfig {
let rustc_source = self.rustc_source().as_ref().map(|rustc_src| { let rustc_source = self.rustc_source().as_ref().map(|rustc_src| {
if rustc_src == "discover" { if rustc_src == "discover" {
RustLibSource::Discover RustLibSource::Discover
@ -1803,7 +1804,7 @@ impl Config {
RustLibSource::Path(self.root_path.join(rustc_src)) RustLibSource::Path(self.root_path.join(rustc_src))
} }
}); });
let sysroot = self.cargo_sysroot().as_ref().map(|sysroot| { let sysroot = self.cargo_sysroot(source_root).as_ref().map(|sysroot| {
if sysroot == "discover" { if sysroot == "discover" {
RustLibSource::Discover RustLibSource::Discover
} else { } else {
@ -1811,24 +1812,24 @@ impl Config {
} }
}); });
let sysroot_src = let sysroot_src =
self.cargo_sysrootSrc().as_ref().map(|sysroot| self.root_path.join(sysroot)); self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot));
CargoConfig { CargoConfig {
all_targets: *self.cargo_allTargets(), all_targets: *self.cargo_allTargets(source_root),
features: match &self.cargo_features() { features: match &self.cargo_features(source_root) {
CargoFeaturesDef::All => CargoFeatures::All, CargoFeaturesDef::All => CargoFeatures::All,
CargoFeaturesDef::Selected(features) => CargoFeatures::Selected { CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
features: features.clone(), features: features.clone(),
no_default_features: self.cargo_noDefaultFeatures().to_owned(), no_default_features: self.cargo_noDefaultFeatures(source_root).to_owned(),
}, },
}, },
target: self.cargo_target().clone(), target: self.cargo_target(source_root).clone(),
sysroot, sysroot,
sysroot_src, sysroot_src,
rustc_source, rustc_source,
cfg_overrides: project_model::CfgOverrides { cfg_overrides: project_model::CfgOverrides {
global: CfgDiff::new( global: CfgDiff::new(
self.cargo_cfgs() self.cargo_cfgs(source_root)
.iter() .iter()
.map(|(key, val)| match val { .map(|(key, val)| match val {
Some(val) => CfgAtom::KeyValue { Some(val) => CfgAtom::KeyValue {
@ -1843,15 +1844,15 @@ impl Config {
.unwrap(), .unwrap(),
selective: Default::default(), selective: Default::default(),
}, },
wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(), wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(source_root),
invocation_strategy: match self.cargo_buildScripts_invocationStrategy() { invocation_strategy: match self.cargo_buildScripts_invocationStrategy(source_root) {
InvocationStrategy::Once => project_model::InvocationStrategy::Once, InvocationStrategy::Once => project_model::InvocationStrategy::Once,
InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace, InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace,
}, },
run_build_script_command: self.cargo_buildScripts_overrideCommand().clone(), run_build_script_command: self.cargo_buildScripts_overrideCommand(source_root).clone(),
extra_args: self.cargo_extraArgs().clone(), extra_args: self.cargo_extraArgs(source_root).clone(),
extra_env: self.cargo_extraEnv().clone(), extra_env: self.cargo_extraEnv(source_root).clone(),
target_dir: self.target_dir_from_config(), target_dir: self.target_dir_from_config(source_root),
} }
} }
@ -1873,24 +1874,24 @@ impl Config {
*self.check_workspace() *self.check_workspace()
} }
pub(crate) fn cargo_test_options(&self) -> CargoOptions { pub(crate) fn cargo_test_options(&self, source_root: Option<SourceRootId>) -> CargoOptions {
CargoOptions { CargoOptions {
target_triples: self.cargo_target().clone().into_iter().collect(), target_triples: self.cargo_target(source_root).clone().into_iter().collect(),
all_targets: false, all_targets: false,
no_default_features: *self.cargo_noDefaultFeatures(), no_default_features: *self.cargo_noDefaultFeatures(source_root),
all_features: matches!(self.cargo_features(), CargoFeaturesDef::All), all_features: matches!(self.cargo_features(source_root), CargoFeaturesDef::All),
features: match self.cargo_features().clone() { features: match self.cargo_features(source_root).clone() {
CargoFeaturesDef::All => vec![], CargoFeaturesDef::All => vec![],
CargoFeaturesDef::Selected(it) => it, CargoFeaturesDef::Selected(it) => it,
}, },
extra_args: self.extra_args().clone(), extra_args: self.extra_args(source_root).clone(),
extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(),
extra_env: self.extra_env().clone(), extra_env: self.extra_env(source_root).clone(),
target_dir: self.target_dir_from_config(), target_dir: self.target_dir_from_config(source_root),
} }
} }
pub(crate) fn flycheck(&self) -> FlycheckConfig { pub(crate) fn flycheck(&self, source_root: Option<SourceRootId>) -> FlycheckConfig {
match &self.check_overrideCommand() { match &self.check_overrideCommand() {
Some(args) if !args.is_empty() => { Some(args) if !args.is_empty() => {
let mut args = args.clone(); let mut args = args.clone();
@ -1898,7 +1899,7 @@ impl Config {
FlycheckConfig::CustomCommand { FlycheckConfig::CustomCommand {
command, command,
args, args,
extra_env: self.check_extra_env(), extra_env: self.check_extra_env(source_root),
invocation_strategy: match self.check_invocationStrategy() { invocation_strategy: match self.check_invocationStrategy() {
InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once, InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once,
InvocationStrategy::PerWorkspace => { InvocationStrategy::PerWorkspace => {
@ -1917,35 +1918,39 @@ impl Config {
[] => None, [] => None,
targets => Some(targets.into()), targets => Some(targets.into()),
}) })
.unwrap_or_else(|| self.cargo_target().clone().into_iter().collect()), .unwrap_or_else(|| {
all_targets: self.check_allTargets().unwrap_or(*self.cargo_allTargets()), self.cargo_target(source_root).clone().into_iter().collect()
}),
all_targets: self
.check_allTargets()
.unwrap_or(*self.cargo_allTargets(source_root)),
no_default_features: self no_default_features: self
.check_noDefaultFeatures() .check_noDefaultFeatures()
.unwrap_or(*self.cargo_noDefaultFeatures()), .unwrap_or(*self.cargo_noDefaultFeatures(source_root)),
all_features: matches!( all_features: matches!(
self.check_features().as_ref().unwrap_or(self.cargo_features()), self.check_features().as_ref().unwrap_or(self.cargo_features(source_root)),
CargoFeaturesDef::All CargoFeaturesDef::All
), ),
features: match self features: match self
.check_features() .check_features()
.clone() .clone()
.unwrap_or_else(|| self.cargo_features().clone()) .unwrap_or_else(|| self.cargo_features(source_root).clone())
{ {
CargoFeaturesDef::All => vec![], CargoFeaturesDef::All => vec![],
CargoFeaturesDef::Selected(it) => it, CargoFeaturesDef::Selected(it) => it,
}, },
extra_args: self.check_extra_args(), extra_args: self.check_extra_args(source_root),
extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(),
extra_env: self.check_extra_env(), extra_env: self.check_extra_env(source_root),
target_dir: self.target_dir_from_config(), target_dir: self.target_dir_from_config(source_root),
}, },
ansi_color_output: self.color_diagnostic_output(), ansi_color_output: self.color_diagnostic_output(),
}, },
} }
} }
fn target_dir_from_config(&self) -> Option<Utf8PathBuf> { fn target_dir_from_config(&self, source_root: Option<SourceRootId>) -> Option<Utf8PathBuf> {
self.cargo_targetDir().as_ref().and_then(|target_dir| match target_dir { self.cargo_targetDir(source_root).as_ref().and_then(|target_dir| match target_dir {
TargetDirectory::UseSubdirectory(true) => { TargetDirectory::UseSubdirectory(true) => {
Some(Utf8PathBuf::from("target/rust-analyzer")) Some(Utf8PathBuf::from("target/rust-analyzer"))
} }
@ -1959,8 +1964,8 @@ impl Config {
*self.checkOnSave() *self.checkOnSave()
} }
pub fn script_rebuild_on_save(&self) -> bool { pub fn script_rebuild_on_save(&self, source_root: Option<SourceRootId>) -> bool {
*self.cargo_buildScripts_rebuildOnSave() *self.cargo_buildScripts_rebuildOnSave(source_root)
} }
pub fn runnables(&self) -> RunnablesConfig { pub fn runnables(&self) -> RunnablesConfig {
@ -3522,9 +3527,9 @@ mod tests {
})); }));
(config, _, _) = config.apply_change(change); (config, _, _) = config.apply_change(change);
assert_eq!(config.cargo_targetDir(), &None); assert_eq!(config.cargo_targetDir(None), &None);
assert!( assert!(
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none()) matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none())
); );
} }
@ -3540,9 +3545,9 @@ mod tests {
(config, _, _) = config.apply_change(change); (config, _, _) = config.apply_change(change);
assert_eq!(config.cargo_targetDir(), &Some(TargetDirectory::UseSubdirectory(true))); assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true)));
assert!( assert!(
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer"))) matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
); );
} }
@ -3559,11 +3564,11 @@ mod tests {
(config, _, _) = config.apply_change(change); (config, _, _) = config.apply_change(change);
assert_eq!( assert_eq!(
config.cargo_targetDir(), config.cargo_targetDir(None),
&Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder"))) &Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder")))
); );
assert!( assert!(
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder"))) matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder")))
); );
} }

View file

@ -631,6 +631,10 @@ impl GlobalStateSnapshot {
file_id_to_url(&self.vfs_read(), id) file_id_to_url(&self.vfs_read(), id)
} }
pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
vfs_path_to_file_id(&self.vfs_read(), vfs_path)
}
pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> { pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> {
let endings = self.vfs.read().1[&file_id]; let endings = self.vfs.read().1[&file_id];
let index = self.analysis.file_line_index(file_id)?; let index = self.analysis.file_line_index(file_id)?;
@ -725,3 +729,9 @@ pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result<FileId
let res = vfs.file_id(&path).ok_or_else(|| anyhow::format_err!("file not found: {path}"))?; let res = vfs.file_id(&path).ok_or_else(|| anyhow::format_err!("file not found: {path}"))?;
Ok(res) Ok(res)
} }
pub(crate) fn vfs_path_to_file_id(vfs: &vfs::Vfs, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
let res =
vfs.file_id(vfs_path).ok_or_else(|| anyhow::format_err!("file not found: {vfs_path}"))?;
Ok(res)
}

View file

@ -145,14 +145,21 @@ pub(crate) fn handle_did_save_text_document(
state: &mut GlobalState, state: &mut GlobalState,
params: DidSaveTextDocumentParams, params: DidSaveTextDocumentParams,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
if state.config.script_rebuild_on_save() && state.build_deps_changed { let mut deps_change_processed = false;
state.build_deps_changed = false;
state
.fetch_build_data_queue
.request_op("build_deps_changed - save notification".to_owned(), ());
}
if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) { if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
let snap = state.snapshot();
let file_id = snap.vfs_path_to_file_id(&vfs_path)?;
let sr = snap.analysis.source_root_id(file_id)?;
deps_change_processed = true;
if state.config.script_rebuild_on_save(Some(sr)) && state.build_deps_changed {
state.build_deps_changed = false;
state
.fetch_build_data_queue
.request_op("build_deps_changed - save notification".to_owned(), ());
}
// Re-fetch workspaces if a workspace related file has changed // Re-fetch workspaces if a workspace related file has changed
if let Some(path) = vfs_path.as_path() { if let Some(path) = vfs_path.as_path() {
let additional_files = &state let additional_files = &state
@ -191,6 +198,17 @@ pub(crate) fn handle_did_save_text_document(
flycheck.restart_workspace(None); flycheck.restart_workspace(None);
} }
} }
if !deps_change_processed
&& state.config.script_rebuild_on_save(None)
&& state.build_deps_changed
{
state.build_deps_changed = false;
state
.fetch_build_data_queue
.request_op("build_deps_changed - save notification".to_owned(), ());
}
Ok(()) Ok(())
} }

View file

@ -256,7 +256,7 @@ pub(crate) fn handle_run_test(
let handle = CargoTestHandle::new( let handle = CargoTestHandle::new(
test_path, test_path,
state.config.cargo_test_options(), state.config.cargo_test_options(None),
cargo.workspace_root(), cargo.workspace_root(),
test_target, test_target,
state.test_run_sender.clone(), state.test_run_sender.clone(),
@ -2119,7 +2119,7 @@ fn run_rustfmt(
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => { RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
// FIXME: Set RUSTUP_TOOLCHAIN // FIXME: Set RUSTUP_TOOLCHAIN
let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path()); let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path());
cmd.envs(snap.config.extra_env()); cmd.envs(snap.config.extra_env(source_root_id));
cmd.args(extra_args); cmd.args(extra_args);
if let Some(edition) = edition { if let Some(edition) = edition {
@ -2177,7 +2177,7 @@ fn run_rustfmt(
_ => process::Command::new(cmd), _ => process::Command::new(cmd),
}; };
cmd.envs(snap.config.extra_env()); cmd.envs(snap.config.extra_env(source_root_id));
cmd.args(args); cmd.args(args);
cmd cmd
} }

View file

@ -455,7 +455,7 @@ impl GlobalState {
} }
} }
if self.config.cargo_autoreload_config() if self.config.cargo_autoreload_config(None)
|| self.config.discover_workspace_config().is_some() || self.config.discover_workspace_config().is_some()
{ {
if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) = if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
@ -973,9 +973,9 @@ impl GlobalState {
// When we're running multiple flychecks, we have to include a disambiguator in // When we're running multiple flychecks, we have to include a disambiguator in
// the title, or the editor complains. Note that this is a user-facing string. // the title, or the editor complains. Note that this is a user-facing string.
let title = if self.flycheck.len() == 1 { let title = if self.flycheck.len() == 1 {
format!("{}", self.config.flycheck()) format!("{}", self.config.flycheck(None))
} else { } else {
format!("{} (#{})", self.config.flycheck(), id + 1) format!("{} (#{})", self.config.flycheck(None), id + 1)
}; };
self.report_progress( self.report_progress(
&title, &title,

View file

@ -100,7 +100,7 @@ impl GlobalState {
{ {
let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false }; let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req) self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req)
} else if self.config.flycheck() != old_config.flycheck() { } else if self.config.flycheck(None) != old_config.flycheck(None) {
self.reload_flycheck(); self.reload_flycheck();
} }
@ -122,7 +122,7 @@ impl GlobalState {
}; };
let mut message = String::new(); let mut message = String::new();
if !self.config.cargo_autoreload() if !self.config.cargo_autoreload(None)
&& self.is_quiescent() && self.is_quiescent()
&& self.fetch_workspaces_queue.op_requested() && self.fetch_workspaces_queue.op_requested()
&& self.config.discover_workspace_config().is_none() && self.config.discover_workspace_config().is_none()
@ -264,7 +264,7 @@ impl GlobalState {
.map(ManifestPath::try_from) .map(ManifestPath::try_from)
.filter_map(Result::ok) .filter_map(Result::ok)
.collect(); .collect();
let cargo_config = self.config.cargo(); let cargo_config = self.config.cargo(None);
let discover_command = self.config.discover_workspace_config().cloned(); let discover_command = self.config.discover_workspace_config().cloned();
let is_quiescent = !(self.discover_workspace_queue.op_in_progress() let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
|| self.vfs_progress_config_version < self.vfs_config_version || self.vfs_progress_config_version < self.vfs_config_version
@ -357,7 +357,7 @@ impl GlobalState {
pub(crate) fn fetch_build_data(&mut self, cause: Cause) { pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
info!(%cause, "will fetch build data"); info!(%cause, "will fetch build data");
let workspaces = Arc::clone(&self.workspaces); let workspaces = Arc::clone(&self.workspaces);
let config = self.config.cargo(); let config = self.config.cargo(None);
let root_path = self.config.root_path().clone(); let root_path = self.config.root_path().clone();
self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| { self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
@ -507,7 +507,7 @@ impl GlobalState {
// FIXME: can we abort the build scripts here if they are already running? // FIXME: can we abort the build scripts here if they are already running?
self.workspaces = Arc::new(workspaces); self.workspaces = Arc::new(workspaces);
if self.config.run_build_scripts() { if self.config.run_build_scripts(None) {
self.build_deps_changed = false; self.build_deps_changed = false;
self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ()); self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ());
} }
@ -627,7 +627,7 @@ impl GlobalState {
.. ..
} => cargo_config_extra_env } => cargo_config_extra_env
.iter() .iter()
.chain(self.config.extra_env()) .chain(self.config.extra_env(None))
.map(|(a, b)| (a.clone(), b.clone())) .map(|(a, b)| (a.clone(), b.clone()))
.chain( .chain(
ws.sysroot ws.sysroot
@ -702,7 +702,7 @@ impl GlobalState {
vfs.file_id(&vfs_path) vfs.file_id(&vfs_path)
}; };
ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load) ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load)
}; };
let mut change = ChangeWithProcMacros::new(); let mut change = ChangeWithProcMacros::new();
if self.config.expand_proc_macros() { if self.config.expand_proc_macros() {
@ -791,7 +791,7 @@ impl GlobalState {
fn reload_flycheck(&mut self) { fn reload_flycheck(&mut self) {
let _p = tracing::info_span!("GlobalState::reload_flycheck").entered(); let _p = tracing::info_span!("GlobalState::reload_flycheck").entered();
let config = self.config.flycheck(); let config = self.config.flycheck(None);
let sender = self.flycheck_sender.clone(); let sender = self.flycheck_sender.clone();
let invocation_strategy = match config { let invocation_strategy = match config {
FlycheckConfig::CargoCommand { .. } => { FlycheckConfig::CargoCommand { .. } => {

View file

@ -168,7 +168,7 @@ impl CargoTargetSpec {
(Default::default(), Default::default()) (Default::default(), Default::default())
}; };
let cargo_config = snap.config.cargo(); let cargo_config = snap.config.cargo(None);
match &cargo_config.features { match &cargo_config.features {
CargoFeatures::All => { CargoFeatures::All => {