Skip to content

Commit 7c53ff2

Browse files
committed
Auto merge of rust-lang#17843 - mo8it:flycheck, r=Veykril
internal: Performance optimizations - Use `Command::arg` directly - Avoid the overhead of the `select!` macro when possible - Use `select_biased!`
2 parents c2d1555 + 204fb5b commit 7c53ff2

File tree

2 files changed

+38
-36
lines changed

2 files changed

+38
-36
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use std::{fmt, io, process::Command, time::Duration};
55

6-
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
6+
use crossbeam_channel::{select_biased, unbounded, Receiver, Sender};
77
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
88
use rustc_hash::FxHashMap;
99
use serde::Deserialize;
@@ -260,13 +260,14 @@ impl FlycheckActor {
260260
}
261261

262262
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
263-
if let Ok(msg) = inbox.try_recv() {
264-
// give restarts a preference so check outputs don't block a restart or stop
265-
return Some(Event::RequestStateChange(msg));
266-
}
267-
select! {
263+
let Some(command_receiver) = &self.command_receiver else {
264+
return inbox.recv().ok().map(Event::RequestStateChange);
265+
};
266+
267+
// Biased to give restarts a preference so check outputs don't block a restart or stop
268+
select_biased! {
268269
recv(inbox) -> msg => msg.ok().map(Event::RequestStateChange),
269-
recv(self.command_receiver.as_ref().unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())),
270+
recv(command_receiver) -> msg => Some(Event::CheckEvent(msg.ok())),
270271
}
271272
}
272273

@@ -388,7 +389,7 @@ impl FlycheckActor {
388389
package: Option<&str>,
389390
saved_file: Option<&AbsPath>,
390391
) -> Option<Command> {
391-
let (mut cmd, args) = match &self.config {
392+
match &self.config {
392393
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
393394
let mut cmd = Command::new(Tool::Cargo.path());
394395
if let Some(sysroot_root) = &self.sysroot_root {
@@ -419,7 +420,8 @@ impl FlycheckActor {
419420
cmd.arg("--keep-going");
420421

421422
options.apply_on_command(&mut cmd);
422-
(cmd, options.extra_args.clone())
423+
cmd.args(&options.extra_args);
424+
Some(cmd)
423425
}
424426
FlycheckConfig::CustomCommand {
425427
command,
@@ -448,34 +450,31 @@ impl FlycheckActor {
448450
}
449451
}
450452

451-
if args.contains(&SAVED_FILE_PLACEHOLDER.to_owned()) {
452-
// If the custom command has a $saved_file placeholder, and
453-
// we're saving a file, replace the placeholder in the arguments.
454-
if let Some(saved_file) = saved_file {
455-
let args = args
456-
.iter()
457-
.map(|arg| {
458-
if arg == SAVED_FILE_PLACEHOLDER {
459-
saved_file.to_string()
460-
} else {
461-
arg.clone()
462-
}
463-
})
464-
.collect();
465-
(cmd, args)
466-
} else {
467-
// The custom command has a $saved_file placeholder,
468-
// but we had an IDE event that wasn't a file save. Do nothing.
469-
return None;
453+
// If the custom command has a $saved_file placeholder, and
454+
// we're saving a file, replace the placeholder in the arguments.
455+
if let Some(saved_file) = saved_file {
456+
for arg in args {
457+
if arg == SAVED_FILE_PLACEHOLDER {
458+
cmd.arg(saved_file);
459+
} else {
460+
cmd.arg(arg);
461+
}
470462
}
471463
} else {
472-
(cmd, args.clone())
464+
for arg in args {
465+
if arg == SAVED_FILE_PLACEHOLDER {
466+
// The custom command has a $saved_file placeholder,
467+
// but we had an IDE event that wasn't a file save. Do nothing.
468+
return None;
469+
}
470+
471+
cmd.arg(arg);
472+
}
473473
}
474-
}
475-
};
476474

477-
cmd.args(args);
478-
Some(cmd)
475+
Some(cmd)
476+
}
477+
}
479478
}
480479

481480
#[track_caller]

src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::{
1313
sync::atomic::AtomicUsize,
1414
};
1515

16-
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
16+
use crossbeam_channel::{select, unbounded, Receiver, Sender};
1717
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
1818
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
1919
use rayon::iter::{IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator};
@@ -85,10 +85,13 @@ impl NotifyActor {
8585
}
8686

8787
fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
88-
let watcher_receiver = self.watcher.as_ref().map(|(_, receiver)| receiver);
88+
let Some((_, watcher_receiver)) = &self.watcher else {
89+
return receiver.recv().ok().map(Event::Message);
90+
};
91+
8992
select! {
9093
recv(receiver) -> it => it.ok().map(Event::Message),
91-
recv(watcher_receiver.unwrap_or(&never())) -> it => Some(Event::NotifyEvent(it.unwrap())),
94+
recv(watcher_receiver) -> it => Some(Event::NotifyEvent(it.unwrap())),
9295
}
9396
}
9497

0 commit comments

Comments
 (0)