Skip to content

Commit ca48c45

Browse files
bors[bot]Jonas Schievink
andauthored
Merge #6027
6027: Spawn a flycheck instance per workspace r=matklad a=jonas-schievink Limitations: - All instances are restarted on every file change - There's only one configuration used for all of them Co-authored-by: Jonas Schievink <[email protected]>
2 parents 662ed41 + 1a28f30 commit ca48c45

File tree

4 files changed

+46
-21
lines changed

4 files changed

+46
-21
lines changed

crates/flycheck/src/lib.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,12 @@ pub struct FlycheckHandle {
5959

6060
impl FlycheckHandle {
6161
pub fn spawn(
62+
id: usize,
6263
sender: Box<dyn Fn(Message) + Send>,
6364
config: FlycheckConfig,
6465
workspace_root: PathBuf,
6566
) -> FlycheckHandle {
66-
let actor = FlycheckActor::new(sender, config, workspace_root);
67+
let actor = FlycheckActor::new(id, sender, config, workspace_root);
6768
let (sender, receiver) = unbounded::<Restart>();
6869
let thread = jod_thread::spawn(move || actor.run(receiver));
6970
FlycheckHandle { sender, thread }
@@ -81,7 +82,11 @@ pub enum Message {
8182
AddDiagnostic { workspace_root: PathBuf, diagnostic: Diagnostic },
8283

8384
/// Request check progress notification to client
84-
Progress(Progress),
85+
Progress {
86+
/// Flycheck instance ID
87+
id: usize,
88+
progress: Progress,
89+
},
8590
}
8691

8792
#[derive(Debug)]
@@ -95,6 +100,7 @@ pub enum Progress {
95100
struct Restart;
96101

97102
struct FlycheckActor {
103+
id: usize,
98104
sender: Box<dyn Fn(Message) + Send>,
99105
config: FlycheckConfig,
100106
workspace_root: PathBuf,
@@ -113,11 +119,15 @@ enum Event {
113119

114120
impl FlycheckActor {
115121
fn new(
122+
id: usize,
116123
sender: Box<dyn Fn(Message) + Send>,
117124
config: FlycheckConfig,
118125
workspace_root: PathBuf,
119126
) -> FlycheckActor {
120-
FlycheckActor { sender, config, workspace_root, cargo_handle: None }
127+
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
128+
}
129+
fn progress(&self, progress: Progress) {
130+
self.send(Message::Progress { id: self.id, progress });
121131
}
122132
fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
123133
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
@@ -139,7 +149,7 @@ impl FlycheckActor {
139149
command.stdout(Stdio::piped()).stderr(Stdio::null()).stdin(Stdio::null());
140150
if let Ok(child) = command.spawn().map(JodChild) {
141151
self.cargo_handle = Some(CargoHandle::spawn(child));
142-
self.send(Message::Progress(Progress::DidStart));
152+
self.progress(Progress::DidStart);
143153
}
144154
}
145155
Event::CheckEvent(None) => {
@@ -153,11 +163,11 @@ impl FlycheckActor {
153163
self.check_command()
154164
)
155165
}
156-
self.send(Message::Progress(Progress::DidFinish(res)));
166+
self.progress(Progress::DidFinish(res));
157167
}
158168
Event::CheckEvent(Some(message)) => match message {
159169
cargo_metadata::Message::CompilerArtifact(msg) => {
160-
self.send(Message::Progress(Progress::DidCheckCrate(msg.target.name)));
170+
self.progress(Progress::DidCheckCrate(msg.target.name));
161171
}
162172

163173
cargo_metadata::Message::CompilerMessage(msg) => {
@@ -179,7 +189,7 @@ impl FlycheckActor {
179189
}
180190
fn cancel_check_process(&mut self) {
181191
if self.cargo_handle.take().is_some() {
182-
self.send(Message::Progress(Progress::DidCancel));
192+
self.progress(Progress::DidCancel);
183193
}
184194
}
185195
fn check_command(&self) -> Command {

crates/rust-analyzer/src/global_state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub(crate) struct GlobalState {
6363
req_queue: ReqQueue,
6464
pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
6565
pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
66-
pub(crate) flycheck: Option<FlycheckHandle>,
66+
pub(crate) flycheck: Vec<FlycheckHandle>,
6767
pub(crate) flycheck_sender: Sender<flycheck::Message>,
6868
pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
6969
pub(crate) config: Config,
@@ -115,7 +115,7 @@ impl GlobalState {
115115
req_queue: ReqQueue::default(),
116116
task_pool,
117117
loader,
118-
flycheck: None,
118+
flycheck: Vec::new(),
119119
flycheck_sender,
120120
flycheck_receiver,
121121
config,

crates/rust-analyzer/src/main_loop.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ impl GlobalState {
266266
}
267267
}
268268

269-
flycheck::Message::Progress(status) => {
270-
let (state, message) = match status {
269+
flycheck::Message::Progress { id, progress } => {
270+
let (state, message) = match progress {
271271
flycheck::Progress::DidStart => {
272272
self.diagnostics.clear_check();
273273
(Progress::Begin, None)
@@ -284,14 +284,21 @@ impl GlobalState {
284284
}
285285
};
286286

287-
self.report_progress("cargo check", state, message, None);
287+
// When we're running multiple flychecks, we have to include a disambiguator in
288+
// the title, or the editor complains. Note that this is a user-facing string.
289+
let title = if self.flycheck.len() == 1 {
290+
"cargo check".to_string()
291+
} else {
292+
format!("cargo check (#{})", id + 1)
293+
};
294+
self.report_progress(&title, state, message, None);
288295
}
289296
},
290297
}
291298

292299
let state_changed = self.process_changes();
293300
if prev_status == Status::Loading && self.status == Status::Ready {
294-
if let Some(flycheck) = &self.flycheck {
301+
for flycheck in &self.flycheck {
295302
flycheck.update();
296303
}
297304
}
@@ -490,7 +497,7 @@ impl GlobalState {
490497
Ok(())
491498
})?
492499
.on::<lsp_types::notification::DidSaveTextDocument>(|this, params| {
493-
if let Some(flycheck) = &this.flycheck {
500+
for flycheck in &this.flycheck {
494501
flycheck.update();
495502
}
496503
if let Ok(abs_path) = from_proto::abs_path(&params.text_document.uri) {

crates/rust-analyzer/src/reload.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,29 +235,37 @@ impl GlobalState {
235235
let config = match self.config.flycheck.clone() {
236236
Some(it) => it,
237237
None => {
238-
self.flycheck = None;
238+
self.flycheck = Vec::new();
239239
return;
240240
}
241241
};
242242

243243
let sender = self.flycheck_sender.clone();
244-
let sender = Box::new(move |msg| sender.send(msg).unwrap());
245244
self.flycheck = self
246245
.workspaces
247246
.iter()
248-
// FIXME: Figure out the multi-workspace situation
249-
.find_map(|w| match w {
250-
ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some(cargo.workspace_root()),
247+
.enumerate()
248+
.filter_map(|(id, w)| match w {
249+
ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some((id, cargo.workspace_root())),
251250
ProjectWorkspace::Json { project, .. } => {
252251
// Enable flychecks for json projects if a custom flycheck command was supplied
253252
// in the workspace configuration.
254253
match config {
255-
FlycheckConfig::CustomCommand { .. } => Some(project.path()),
254+
FlycheckConfig::CustomCommand { .. } => Some((id, project.path())),
256255
_ => None,
257256
}
258257
}
259258
})
260-
.map(move |root| FlycheckHandle::spawn(sender, config, root.to_path_buf().into()))
259+
.map(|(id, root)| {
260+
let sender = sender.clone();
261+
FlycheckHandle::spawn(
262+
id,
263+
Box::new(move |msg| sender.send(msg).unwrap()),
264+
config.clone(),
265+
root.to_path_buf().into(),
266+
)
267+
})
268+
.collect();
261269
}
262270
}
263271

0 commit comments

Comments
 (0)