Skip to content

Commit 43fb956

Browse files
committed
Auto merge of rust-lang#13471 - Veykril:invoc-strategy-once, r=Veykril
Handle multiple projects sharing dependency correctly in `once` strategy
2 parents b25f657 + 859f559 commit 43fb956

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

crates/project-model/src/build_scripts.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl BuildScriptOutput {
5656
}
5757

5858
impl WorkspaceBuildScripts {
59-
fn build_command(config: &CargoConfig, current_dir: &path::Path) -> io::Result<Command> {
59+
fn build_command(config: &CargoConfig) -> io::Result<Command> {
6060
let mut cmd = match config.run_build_script_command.as_deref() {
6161
Some([program, args @ ..]) => {
6262
let mut cmd = Command::new(program);
@@ -96,7 +96,6 @@ impl WorkspaceBuildScripts {
9696
}
9797
};
9898

99-
cmd.current_dir(current_dir);
10099
cmd.envs(&config.extra_env);
101100
if config.wrap_rustc_in_build_scripts {
102101
// Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
@@ -127,15 +126,15 @@ impl WorkspaceBuildScripts {
127126
}
128127
.as_ref();
129128

130-
match Self::run_per_ws(Self::build_command(config, current_dir)?, workspace, progress) {
129+
match Self::run_per_ws(Self::build_command(config)?, workspace, current_dir, progress) {
131130
Ok(WorkspaceBuildScripts { error: Some(error), .. })
132131
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
133132
{
134133
// building build scripts failed, attempt to build with --keep-going so
135134
// that we potentially get more build data
136-
let mut cmd = Self::build_command(config, current_dir)?;
135+
let mut cmd = Self::build_command(config)?;
137136
cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
138-
let mut res = Self::run_per_ws(cmd, workspace, progress)?;
137+
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
139138
res.error = Some(error);
140139
Ok(res)
141140
}
@@ -161,26 +160,34 @@ impl WorkspaceBuildScripts {
161160
))
162161
}
163162
};
164-
let cmd = Self::build_command(config, current_dir.as_path().as_ref())?;
163+
let cmd = Self::build_command(config)?;
165164
// NB: Cargo.toml could have been modified between `cargo metadata` and
166165
// `cargo check`. We shouldn't assume that package ids we see here are
167166
// exactly those from `config`.
168167
let mut by_id = FxHashMap::default();
168+
// some workspaces might depend on the same crates, so we need to duplicate the outputs
169+
// to those collisions
170+
let mut collisions = Vec::new();
169171
let mut res: Vec<_> = workspaces
170172
.iter()
171173
.enumerate()
172174
.map(|(idx, workspace)| {
173175
let mut res = WorkspaceBuildScripts::default();
174176
for package in workspace.packages() {
175177
res.outputs.insert(package, BuildScriptOutput::default());
176-
by_id.insert(workspace[package].id.clone(), (package, idx));
178+
if by_id.contains_key(&workspace[package].id) {
179+
collisions.push((&workspace[package].id, idx, package));
180+
} else {
181+
by_id.insert(workspace[package].id.clone(), (package, idx));
182+
}
177183
}
178184
res
179185
})
180186
.collect();
181187

182188
let errors = Self::run_command(
183189
cmd,
190+
current_dir.as_path().as_ref(),
184191
|package, cb| {
185192
if let Some(&(package, workspace)) = by_id.get(package) {
186193
cb(&workspaces[workspace][package].name, &mut res[workspace].outputs[package]);
@@ -189,6 +196,11 @@ impl WorkspaceBuildScripts {
189196
progress,
190197
)?;
191198
res.iter_mut().for_each(|it| it.error = errors.clone());
199+
collisions.into_iter().for_each(|(id, workspace, package)| {
200+
if let Some(&(p, w)) = by_id.get(id) {
201+
res[workspace].outputs[package] = res[w].outputs[p].clone();
202+
}
203+
});
192204

193205
if tracing::enabled!(tracing::Level::INFO) {
194206
for (idx, workspace) in workspaces.iter().enumerate() {
@@ -211,6 +223,7 @@ impl WorkspaceBuildScripts {
211223
fn run_per_ws(
212224
cmd: Command,
213225
workspace: &CargoWorkspace,
226+
current_dir: &path::Path,
214227
progress: &dyn Fn(String),
215228
) -> io::Result<WorkspaceBuildScripts> {
216229
let mut res = WorkspaceBuildScripts::default();
@@ -226,6 +239,7 @@ impl WorkspaceBuildScripts {
226239

227240
res.error = Self::run_command(
228241
cmd,
242+
current_dir,
229243
|package, cb| {
230244
if let Some(&package) = by_id.get(package) {
231245
cb(&workspace[package].name, &mut outputs[package]);
@@ -251,7 +265,8 @@ impl WorkspaceBuildScripts {
251265
}
252266

253267
fn run_command(
254-
cmd: Command,
268+
mut cmd: Command,
269+
current_dir: &path::Path,
255270
// ideally this would be something like:
256271
// with_output_for: impl FnMut(&str, dyn FnOnce(&mut BuildScriptOutput)),
257272
// but owned trait objects aren't a thing
@@ -265,7 +280,8 @@ impl WorkspaceBuildScripts {
265280
e.push('\n');
266281
};
267282

268-
tracing::info!("Running build scripts: {:?}", cmd);
283+
tracing::info!("Running build scripts in {}: {:?}", current_dir.display(), cmd);
284+
cmd.current_dir(current_dir);
269285
let output = stdx::process::spawn_with_streaming_output(
270286
cmd,
271287
&mut |line| {

crates/project-model/src/workspace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl ProjectWorkspace {
333333
progress: &dyn Fn(String),
334334
) -> Vec<Result<WorkspaceBuildScripts>> {
335335
if matches!(config.invocation_strategy, InvocationStrategy::PerWorkspace)
336-
|| config.run_build_script_command.is_some()
336+
|| config.run_build_script_command.is_none()
337337
{
338338
return workspaces.iter().map(|it| it.run_build_scripts(config, progress)).collect();
339339
}

crates/rust-analyzer/src/main_loop.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,10 @@ impl GlobalState {
543543
diag.fix,
544544
),
545545
Err(err) => {
546-
tracing::error!("File with cargo diagnostic not found in VFS: {}", err);
546+
tracing::error!(
547+
"flycheck {id}: File with cargo diagnostic not found in VFS: {}",
548+
err
549+
);
547550
}
548551
};
549552
}

0 commit comments

Comments
 (0)