diff options
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 | ||
77 | struct SubDiagnostic { | ||
78 | related: lsp_types::DiagnosticRelatedInformation, | ||
79 | suggested_fix: Option<lsp_ext::CodeAction>, | ||
80 | } | ||
81 | |||
77 | enum MappedRustChildDiagnostic { | 82 | enum 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, |