Skip to content

Commit d400fde

Browse files
bors[bot]kiljacken
andauthored
Merge #2959
2959: Rework how we send diagnostics to client r=matklad a=kiljacken The previous way of sending from the thread pool suffered from stale diagnostics due to being canceled before we could clear the old ones. The key change is moving to sending diagnostics from the main loop thread, but doing all the hard work in the thread pool. This should provide the best of both worlds, with little to no of the downsides. This should hopefully fix a lot of issues, but we'll need testing in each individual issue to be sure. Co-authored-by: Emil Lauridsen <[email protected]>
2 parents 5b1b2ca + 9f70f44 commit d400fde

14 files changed

+244
-247
lines changed

crates/ra_cargo_watch/src/conv.rs

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! This module provides the functionality needed to convert diagnostics from
22
//! `cargo check` json format to the LSP diagnostic format.
33
use cargo_metadata::diagnostic::{
4-
Applicability, Diagnostic as RustDiagnostic, DiagnosticLevel, DiagnosticSpan,
5-
DiagnosticSpanMacroExpansion,
4+
Diagnostic as RustDiagnostic, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion,
65
};
76
use lsp_types::{
8-
Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Location,
9-
NumberOrString, Position, Range, Url,
7+
CodeAction, Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag,
8+
Location, NumberOrString, Position, Range, TextEdit, Url, WorkspaceEdit,
109
};
1110
use std::{
1211
fmt::Write,
@@ -117,38 +116,9 @@ fn is_deprecated(rd: &RustDiagnostic) -> bool {
117116
}
118117
}
119118

120-
#[derive(Clone, Debug)]
121-
pub struct SuggestedFix {
122-
pub title: String,
123-
pub location: Location,
124-
pub replacement: String,
125-
pub applicability: Applicability,
126-
pub diagnostics: Vec<Diagnostic>,
127-
}
128-
129-
impl std::cmp::PartialEq<SuggestedFix> for SuggestedFix {
130-
fn eq(&self, other: &SuggestedFix) -> bool {
131-
if self.title == other.title
132-
&& self.location == other.location
133-
&& self.replacement == other.replacement
134-
{
135-
// Applicability doesn't impl PartialEq...
136-
match (&self.applicability, &other.applicability) {
137-
(Applicability::MachineApplicable, Applicability::MachineApplicable) => true,
138-
(Applicability::HasPlaceholders, Applicability::HasPlaceholders) => true,
139-
(Applicability::MaybeIncorrect, Applicability::MaybeIncorrect) => true,
140-
(Applicability::Unspecified, Applicability::Unspecified) => true,
141-
_ => false,
142-
}
143-
} else {
144-
false
145-
}
146-
}
147-
}
148-
149119
enum MappedRustChildDiagnostic {
150120
Related(DiagnosticRelatedInformation),
151-
SuggestedFix(SuggestedFix),
121+
SuggestedFix(CodeAction),
152122
MessageLine(String),
153123
}
154124

@@ -176,12 +146,20 @@ fn map_rust_child_diagnostic(
176146
rd.message.clone()
177147
};
178148

179-
MappedRustChildDiagnostic::SuggestedFix(SuggestedFix {
149+
let edit = {
150+
let edits = vec![TextEdit::new(location.range, suggested_replacement.clone())];
151+
let mut edit_map = std::collections::HashMap::new();
152+
edit_map.insert(location.uri, edits);
153+
WorkspaceEdit::new(edit_map)
154+
};
155+
156+
MappedRustChildDiagnostic::SuggestedFix(CodeAction {
180157
title,
181-
location,
182-
replacement: suggested_replacement.clone(),
183-
applicability: span.suggestion_applicability.clone().unwrap_or(Applicability::Unknown),
184-
diagnostics: vec![],
158+
kind: Some("quickfix".to_string()),
159+
diagnostics: None,
160+
edit: Some(edit),
161+
command: None,
162+
is_preferred: None,
185163
})
186164
} else {
187165
MappedRustChildDiagnostic::Related(DiagnosticRelatedInformation {
@@ -195,7 +173,7 @@ fn map_rust_child_diagnostic(
195173
pub(crate) struct MappedRustDiagnostic {
196174
pub location: Location,
197175
pub diagnostic: Diagnostic,
198-
pub suggested_fixes: Vec<SuggestedFix>,
176+
pub fixes: Vec<CodeAction>,
199177
}
200178

201179
/// Converts a Rust root diagnostic to LSP form
@@ -250,15 +228,13 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
250228
}
251229
}
252230

253-
let mut suggested_fixes = vec![];
231+
let mut fixes = vec![];
254232
let mut message = rd.message.clone();
255233
for child in &rd.children {
256234
let child = map_rust_child_diagnostic(&child, workspace_root);
257235
match child {
258236
MappedRustChildDiagnostic::Related(related) => related_information.push(related),
259-
MappedRustChildDiagnostic::SuggestedFix(suggested_fix) => {
260-
suggested_fixes.push(suggested_fix)
261-
}
237+
MappedRustChildDiagnostic::SuggestedFix(code_action) => fixes.push(code_action.into()),
262238
MappedRustChildDiagnostic::MessageLine(message_line) => {
263239
write!(&mut message, "\n{}", message_line).unwrap();
264240

@@ -295,7 +271,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
295271
tags: if !tags.is_empty() { Some(tags) } else { None },
296272
};
297273

298-
Some(MappedRustDiagnostic { location, diagnostic, suggested_fixes })
274+
Some(MappedRustDiagnostic { location, diagnostic, fixes })
299275
}
300276

301277
/// Returns a `Url` object from a given path, will lowercase drive letters if present.

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_clippy_pass_by_ref.snap

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,39 @@ MappedRustDiagnostic {
6161
),
6262
tags: None,
6363
},
64-
suggested_fixes: [
65-
SuggestedFix {
64+
fixes: [
65+
CodeAction {
6666
title: "consider passing by value instead: \'self\'",
67-
location: Location {
68-
uri: "file:///test/compiler/mir/tagset.rs",
69-
range: Range {
70-
start: Position {
71-
line: 41,
72-
character: 23,
73-
},
74-
end: Position {
75-
line: 41,
76-
character: 28,
77-
},
67+
kind: Some(
68+
"quickfix",
69+
),
70+
diagnostics: None,
71+
edit: Some(
72+
WorkspaceEdit {
73+
changes: Some(
74+
{
75+
"file:///test/compiler/mir/tagset.rs": [
76+
TextEdit {
77+
range: Range {
78+
start: Position {
79+
line: 41,
80+
character: 23,
81+
},
82+
end: Position {
83+
line: 41,
84+
character: 28,
85+
},
86+
},
87+
new_text: "self",
88+
},
89+
],
90+
},
91+
),
92+
document_changes: None,
7893
},
79-
},
80-
replacement: "self",
81-
applicability: Unspecified,
82-
diagnostics: [],
94+
),
95+
command: None,
96+
is_preferred: None,
8397
},
8498
],
8599
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_handles_macro_location.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ MappedRustDiagnostic {
4242
related_information: None,
4343
tags: None,
4444
},
45-
suggested_fixes: [],
45+
fixes: [],
4646
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_macro_compiler_error.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,5 @@ MappedRustDiagnostic {
5757
),
5858
tags: None,
5959
},
60-
suggested_fixes: [],
60+
fixes: [],
6161
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_incompatible_type_for_trait.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ MappedRustDiagnostic {
4242
related_information: None,
4343
tags: None,
4444
},
45-
suggested_fixes: [],
45+
fixes: [],
4646
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_mismatched_type.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ MappedRustDiagnostic {
4242
related_information: None,
4343
tags: None,
4444
},
45-
suggested_fixes: [],
45+
fixes: [],
4646
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_unused_variable.snap

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,39 @@ MappedRustDiagnostic {
4646
],
4747
),
4848
},
49-
suggested_fixes: [
50-
SuggestedFix {
49+
fixes: [
50+
CodeAction {
5151
title: "consider prefixing with an underscore: \'_foo\'",
52-
location: Location {
53-
uri: "file:///test/driver/subcommand/repl.rs",
54-
range: Range {
55-
start: Position {
56-
line: 290,
57-
character: 8,
58-
},
59-
end: Position {
60-
line: 290,
61-
character: 11,
62-
},
52+
kind: Some(
53+
"quickfix",
54+
),
55+
diagnostics: None,
56+
edit: Some(
57+
WorkspaceEdit {
58+
changes: Some(
59+
{
60+
"file:///test/driver/subcommand/repl.rs": [
61+
TextEdit {
62+
range: Range {
63+
start: Position {
64+
line: 290,
65+
character: 8,
66+
},
67+
end: Position {
68+
line: 290,
69+
character: 11,
70+
},
71+
},
72+
new_text: "_foo",
73+
},
74+
],
75+
},
76+
),
77+
document_changes: None,
6378
},
64-
},
65-
replacement: "_foo",
66-
applicability: MachineApplicable,
67-
diagnostics: [],
79+
),
80+
command: None,
81+
is_preferred: None,
6882
},
6983
],
7084
}

crates/ra_cargo_watch/src/conv/snapshots/ra_cargo_watch__conv__test__snap_rustc_wrong_number_of_parameters.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,5 @@ MappedRustDiagnostic {
6161
),
6262
tags: None,
6363
},
64-
suggested_fixes: [],
64+
fixes: [],
6565
}

0 commit comments

Comments
 (0)