aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/diagnostics
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-01-15 17:11:54 +0000
committerJonas Schievink <[email protected]>2021-01-15 17:11:54 +0000
commit36500fe49630f0ac29e57ff1af737b2bd7bff5a8 (patch)
tree8444807099e9ec907235fabb431c072a8ecc81d4 /crates/rust-analyzer/src/diagnostics
parent0c58aa9dc0e24f0fa6a6ee7eb0c35041dedddb0a (diff)
Don't duplicate rustc diagnostics fixes
Diffstat (limited to 'crates/rust-analyzer/src/diagnostics')
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt47
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt47
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt47
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt120
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs53
5 files changed, 32 insertions, 282 deletions
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
index 23d42b4d0..5c282fe67 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt
@@ -66,52 +66,7 @@
66 ), 66 ),
67 data: None, 67 data: None,
68 }, 68 },
69 fixes: [ 69 fixes: [],
70 CodeAction {
71 title: "consider prefixing with an underscore",
72 group: None,
73 kind: Some(
74 CodeActionKind(
75 "quickfix",
76 ),
77 ),
78 edit: Some(
79 SnippetWorkspaceEdit {
80 changes: Some(
81 {
82 Url {
83 scheme: "file",
84 host: None,
85 port: None,
86 path: "/test/driver/subcommand/repl.rs",
87 query: None,
88 fragment: None,
89 }: [
90 TextEdit {
91 range: Range {
92 start: Position {
93 line: 290,
94 character: 8,
95 },
96 end: Position {
97 line: 290,
98 character: 11,
99 },
100 },
101 new_text: "_foo",
102 },
103 ],
104 },
105 ),
106 document_changes: None,
107 },
108 ),
109 is_preferred: Some(
110 true,
111 ),
112 data: None,
113 },
114 ],
115 }, 70 },
116 MappedRustDiagnostic { 71 MappedRustDiagnostic {
117 url: Url { 72 url: Url {
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
index 4e428bedc..d36d7693d 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt
@@ -66,52 +66,7 @@
66 ), 66 ),
67 data: None, 67 data: None,
68 }, 68 },
69 fixes: [ 69 fixes: [],
70 CodeAction {
71 title: "consider prefixing with an underscore",
72 group: None,
73 kind: Some(
74 CodeActionKind(
75 "quickfix",
76 ),
77 ),
78 edit: Some(
79 SnippetWorkspaceEdit {
80 changes: Some(
81 {
82 Url {
83 scheme: "file",
84 host: None,
85 port: None,
86 path: "/test/driver/subcommand/repl.rs",
87 query: None,
88 fragment: None,
89 }: [
90 TextEdit {
91 range: Range {
92 start: Position {
93 line: 290,
94 character: 8,
95 },
96 end: Position {
97 line: 290,
98 character: 11,
99 },
100 },
101 new_text: "_foo",
102 },
103 ],
104 },
105 ),
106 document_changes: None,
107 },
108 ),
109 is_preferred: Some(
110 true,
111 ),
112 data: None,
113 },
114 ],
115 }, 70 },
116 MappedRustDiagnostic { 71 MappedRustDiagnostic {
117 url: Url { 72 url: Url {
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
index 4ddd7efae..17845b711 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt
@@ -66,52 +66,7 @@
66 ), 66 ),
67 data: None, 67 data: None,
68 }, 68 },
69 fixes: [ 69 fixes: [],
70 CodeAction {
71 title: "consider prefixing with an underscore",
72 group: None,
73 kind: Some(
74 CodeActionKind(
75 "quickfix",
76 ),
77 ),
78 edit: Some(
79 SnippetWorkspaceEdit {
80 changes: Some(
81 {
82 Url {
83 scheme: "file",
84 host: None,
85 port: None,
86 path: "/test/driver/subcommand/repl.rs",
87 query: None,
88 fragment: None,
89 }: [
90 TextEdit {
91 range: Range {
92 start: Position {
93 line: 290,
94 character: 8,
95 },
96 end: Position {
97 line: 290,
98 character: 11,
99 },
100 },
101 new_text: "_foo",
102 },
103 ],
104 },
105 ),
106 document_changes: None,
107 },
108 ),
109 is_preferred: Some(
110 true,
111 ),
112 data: None,
113 },
114 ],
115 }, 70 },
116 MappedRustDiagnostic { 71 MappedRustDiagnostic {
117 url: Url { 72 url: Url {
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
index 4cbdb3b92..a19962167 100644
--- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
+++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt
@@ -102,65 +102,7 @@
102 tags: None, 102 tags: None,
103 data: None, 103 data: None,
104 }, 104 },
105 fixes: [ 105 fixes: [],
106 CodeAction {
107 title: "return the expression directly",
108 group: None,
109 kind: Some(
110 CodeActionKind(
111 "quickfix",
112 ),
113 ),
114 edit: Some(
115 SnippetWorkspaceEdit {
116 changes: Some(
117 {
118 Url {
119 scheme: "file",
120 host: None,
121 port: None,
122 path: "/test/src/main.rs",
123 query: None,
124 fragment: None,
125 }: [
126 TextEdit {
127 range: Range {
128 start: Position {
129 line: 2,
130 character: 4,
131 },
132 end: Position {
133 line: 2,
134 character: 30,
135 },
136 },
137 new_text: "",
138 },
139 TextEdit {
140 range: Range {
141 start: Position {
142 line: 3,
143 character: 4,
144 },
145 end: Position {
146 line: 3,
147 character: 5,
148 },
149 },
150 new_text: "(0..10).collect()",
151 },
152 ],
153 },
154 ),
155 document_changes: None,
156 },
157 ),
158 is_preferred: Some(
159 true,
160 ),
161 data: None,
162 },
163 ],
164 }, 106 },
165 MappedRustDiagnostic { 107 MappedRustDiagnostic {
166 url: Url { 108 url: Url {
@@ -242,65 +184,7 @@
242 tags: None, 184 tags: None,
243 data: None, 185 data: None,
244 }, 186 },
245 fixes: [ 187 fixes: [],
246 CodeAction {
247 title: "return the expression directly",
248 group: None,
249 kind: Some(
250 CodeActionKind(
251 "quickfix",
252 ),
253 ),
254 edit: Some(
255 SnippetWorkspaceEdit {
256 changes: Some(
257 {
258 Url {
259 scheme: "file",
260 host: None,
261 port: None,
262 path: "/test/src/main.rs",
263 query: None,
264 fragment: None,
265 }: [
266 TextEdit {
267 range: Range {
268 start: Position {
269 line: 2,
270 character: 4,
271 },
272 end: Position {
273 line: 2,
274 character: 30,
275 },
276 },
277 new_text: "",
278 },
279 TextEdit {
280 range: Range {
281 start: Position {
282 line: 3,
283 character: 4,
284 },
285 end: Position {
286 line: 3,
287 character: 5,
288 },
289 },
290 new_text: "(0..10).collect()",
291 },
292 ],
293 },
294 ),
295 document_changes: None,
296 },
297 ),
298 is_preferred: Some(
299 true,
300 ),
301 data: None,
302 },
303 ],
304 }, 188 },
305 MappedRustDiagnostic { 189 MappedRustDiagnostic {
306 url: Url { 190 url: Url {
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 540759198..757899484 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -74,11 +74,13 @@ fn diagnostic_related_information(
74 Some(lsp_types::DiagnosticRelatedInformation { location, message }) 74 Some(lsp_types::DiagnosticRelatedInformation { location, message })
75} 75}
76 76
77struct SubDiagnostic {
78 related: lsp_types::DiagnosticRelatedInformation,
79 suggested_fix: Option<lsp_ext::CodeAction>,
80}
81
77enum MappedRustChildDiagnostic { 82enum MappedRustChildDiagnostic {
78 Related { 83 SubDiagnostic(SubDiagnostic),
79 related: lsp_types::DiagnosticRelatedInformation,
80 suggested_fix: Option<lsp_ext::CodeAction>,
81 },
82 MessageLine(String), 84 MessageLine(String),
83} 85}
84 86
@@ -105,15 +107,15 @@ fn map_rust_child_diagnostic(
105 } 107 }
106 108
107 if edit_map.is_empty() { 109 if edit_map.is_empty() {
108 MappedRustChildDiagnostic::Related { 110 MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic {
109 related: lsp_types::DiagnosticRelatedInformation { 111 related: lsp_types::DiagnosticRelatedInformation {
110 location: location(workspace_root, spans[0]), 112 location: location(workspace_root, spans[0]),
111 message: rd.message.clone(), 113 message: rd.message.clone(),
112 }, 114 },
113 suggested_fix: None, 115 suggested_fix: None,
114 } 116 })
115 } else { 117 } else {
116 MappedRustChildDiagnostic::Related { 118 MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic {
117 related: lsp_types::DiagnosticRelatedInformation { 119 related: lsp_types::DiagnosticRelatedInformation {
118 location: location(workspace_root, spans[0]), 120 location: location(workspace_root, spans[0]),
119 message: rd.message.clone(), 121 message: rd.message.clone(),
@@ -130,7 +132,7 @@ fn map_rust_child_diagnostic(
130 is_preferred: Some(true), 132 is_preferred: Some(true),
131 data: None, 133 data: None,
132 }), 134 }),
133 } 135 })
134 } 136 }
135} 137}
136 138
@@ -175,26 +177,22 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
175 } 177 }
176 178
177 let mut needs_primary_span_label = true; 179 let mut needs_primary_span_label = true;
178 let mut related_information = Vec::new(); 180 let mut subdiagnostics = Vec::new();
179 let mut tags = Vec::new(); 181 let mut tags = Vec::new();
180 182
181 for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { 183 for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) {
182 let related = diagnostic_related_information(workspace_root, secondary_span); 184 let related = diagnostic_related_information(workspace_root, secondary_span);
183 if let Some(related) = related { 185 if let Some(related) = related {
184 related_information.push(related); 186 subdiagnostics.push(SubDiagnostic { related, suggested_fix: None });
185 } 187 }
186 } 188 }
187 189
188 let mut fixes = Vec::new();
189 let mut message = rd.message.clone(); 190 let mut message = rd.message.clone();
190 for child in &rd.children { 191 for child in &rd.children {
191 let child = map_rust_child_diagnostic(workspace_root, &child); 192 let child = map_rust_child_diagnostic(workspace_root, &child);
192 match child { 193 match child {
193 MappedRustChildDiagnostic::Related { related, suggested_fix } => { 194 MappedRustChildDiagnostic::SubDiagnostic(sub) => {
194 related_information.push(related); 195 subdiagnostics.push(sub);
195 if let Some(code_action) = suggested_fix {
196 fixes.push(code_action);
197 }
198 } 196 }
199 MappedRustChildDiagnostic::MessageLine(message_line) => { 197 MappedRustChildDiagnostic::MessageLine(message_line) => {
200 format_to!(message, "\n{}", message_line); 198 format_to!(message, "\n{}", message_line);
@@ -284,7 +282,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
284 diagnostics.push(MappedRustDiagnostic { 282 diagnostics.push(MappedRustDiagnostic {
285 url: in_macro_location.uri, 283 url: in_macro_location.uri,
286 diagnostic, 284 diagnostic,
287 fixes: fixes.clone(), 285 fixes: Vec::new(),
288 }); 286 });
289 } 287 }
290 288
@@ -298,17 +296,20 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
298 code_description: code_description.clone(), 296 code_description: code_description.clone(),
299 source: Some(source.clone()), 297 source: Some(source.clone()),
300 message, 298 message,
301 related_information: if related_information.is_empty() { 299 related_information: if subdiagnostics.is_empty() {
302 None 300 None
303 } else { 301 } else {
304 let mut related = related_information.clone(); 302 let mut related = subdiagnostics
303 .iter()
304 .map(|sub| sub.related.clone())
305 .collect::<Vec<_>>();
305 related.extend(related_macro_info); 306 related.extend(related_macro_info);
306 Some(related) 307 Some(related)
307 }, 308 },
308 tags: if tags.is_empty() { None } else { Some(tags.clone()) }, 309 tags: if tags.is_empty() { None } else { Some(tags.clone()) },
309 data: None, 310 data: None,
310 }, 311 },
311 fixes: fixes.clone(), 312 fixes: Vec::new(),
312 }); 313 });
313 314
314 // Emit hint-level diagnostics for all `related_information` entries such as "help"s. 315 // Emit hint-level diagnostics for all `related_information` entries such as "help"s.
@@ -318,21 +319,21 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
318 location, 319 location,
319 message: "original diagnostic".to_string(), 320 message: "original diagnostic".to_string(),
320 }; 321 };
321 for info in &related_information { 322 for sub in &subdiagnostics {
322 // Filter out empty/non-existent messages, as they greatly confuse VS Code. 323 // Filter out empty/non-existent messages, as they greatly confuse VS Code.
323 if info.message.is_empty() { 324 if sub.related.message.is_empty() {
324 continue; 325 continue;
325 } 326 }
326 diagnostics.push(MappedRustDiagnostic { 327 diagnostics.push(MappedRustDiagnostic {
327 url: info.location.uri.clone(), 328 url: sub.related.location.uri.clone(),
328 fixes: fixes.clone(), // share fixes to make them easier to apply 329 fixes: sub.suggested_fix.iter().cloned().collect(),
329 diagnostic: lsp_types::Diagnostic { 330 diagnostic: lsp_types::Diagnostic {
330 range: info.location.range, 331 range: sub.related.location.range,
331 severity: Some(lsp_types::DiagnosticSeverity::Hint), 332 severity: Some(lsp_types::DiagnosticSeverity::Hint),
332 code: code.clone().map(lsp_types::NumberOrString::String), 333 code: code.clone().map(lsp_types::NumberOrString::String),
333 code_description: code_description.clone(), 334 code_description: code_description.clone(),
334 source: Some(source.clone()), 335 source: Some(source.clone()),
335 message: info.message.clone(), 336 message: sub.related.message.clone(),
336 related_information: Some(vec![back_ref.clone()]), 337 related_information: Some(vec![back_ref.clone()]),
337 tags: None, // don't apply modifiers again 338 tags: None, // don't apply modifiers again
338 data: None, 339 data: None,