diff options
author | Emil Lauridsen <[email protected]> | 2020-03-12 14:24:20 +0000 |
---|---|---|
committer | Emil Lauridsen <[email protected]> | 2020-03-12 14:24:20 +0000 |
commit | 98e8ad5e608b739d1d28a43c8c69358e77c1c1f0 (patch) | |
tree | 5a94c369d38da4a9e5d5598f57e0b8f8d9d5ded9 /crates/ra_cargo_watch/src/conv.rs | |
parent | 637c795b3c9a56795977ade0cedbc7a9fb7dc453 (diff) |
Handle diagnostics with multiple primary spans
Diffstat (limited to 'crates/ra_cargo_watch/src/conv.rs')
-rw-r--r-- | crates/ra_cargo_watch/src/conv.rs | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/crates/ra_cargo_watch/src/conv.rs b/crates/ra_cargo_watch/src/conv.rs index a3f05bede..c6f8ca329 100644 --- a/crates/ra_cargo_watch/src/conv.rs +++ b/crates/ra_cargo_watch/src/conv.rs | |||
@@ -180,13 +180,13 @@ pub(crate) struct MappedRustDiagnostic { | |||
180 | pub(crate) fn map_rust_diagnostic_to_lsp( | 180 | pub(crate) fn map_rust_diagnostic_to_lsp( |
181 | rd: &RustDiagnostic, | 181 | rd: &RustDiagnostic, |
182 | workspace_root: &PathBuf, | 182 | workspace_root: &PathBuf, |
183 | ) -> Option<MappedRustDiagnostic> { | 183 | ) -> Vec<MappedRustDiagnostic> { |
184 | let primary_span = rd.spans.iter().find(|s| s.is_primary)?; | 184 | let primary_spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect(); |
185 | 185 | if primary_spans.is_empty() { | |
186 | let location = map_span_to_location(&primary_span, workspace_root); | 186 | return vec![]; |
187 | } | ||
187 | 188 | ||
188 | let severity = map_level_to_severity(rd.level); | 189 | let severity = map_level_to_severity(rd.level); |
189 | let mut primary_span_label = primary_span.label.as_ref(); | ||
190 | 190 | ||
191 | let mut source = String::from("rustc"); | 191 | let mut source = String::from("rustc"); |
192 | let mut code = rd.code.as_ref().map(|c| c.code.clone()); | 192 | let mut code = rd.code.as_ref().map(|c| c.code.clone()); |
@@ -199,19 +199,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | let mut needs_primary_span_label = true; | ||
202 | let mut related_information = vec![]; | 203 | let mut related_information = vec![]; |
203 | let mut tags = vec![]; | 204 | let mut tags = vec![]; |
204 | 205 | ||
205 | // If error occurs from macro expansion, add related info pointing to | ||
206 | // where the error originated | ||
207 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { | ||
208 | let def_loc = map_span_to_location_naive(&primary_span, workspace_root); | ||
209 | related_information.push(DiagnosticRelatedInformation { | ||
210 | location: def_loc, | ||
211 | message: "Error originated from macro here".to_string(), | ||
212 | }); | ||
213 | } | ||
214 | |||
215 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { | 206 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { |
216 | let related = map_secondary_span_to_related(secondary_span, workspace_root); | 207 | let related = map_secondary_span_to_related(secondary_span, workspace_root); |
217 | if let Some(related) = related { | 208 | if let Some(related) = related { |
@@ -231,15 +222,11 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
231 | 222 | ||
232 | // These secondary messages usually duplicate the content of the | 223 | // These secondary messages usually duplicate the content of the |
233 | // primary span label. | 224 | // primary span label. |
234 | primary_span_label = None; | 225 | needs_primary_span_label = false; |
235 | } | 226 | } |
236 | } | 227 | } |
237 | } | 228 | } |
238 | 229 | ||
239 | if let Some(primary_span_label) = primary_span_label { | ||
240 | write!(&mut message, "\n{}", primary_span_label).unwrap(); | ||
241 | } | ||
242 | |||
243 | if is_unused_or_unnecessary(rd) { | 230 | if is_unused_or_unnecessary(rd) { |
244 | tags.push(DiagnosticTag::Unnecessary); | 231 | tags.push(DiagnosticTag::Unnecessary); |
245 | } | 232 | } |
@@ -248,21 +235,45 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
248 | tags.push(DiagnosticTag::Deprecated); | 235 | tags.push(DiagnosticTag::Deprecated); |
249 | } | 236 | } |
250 | 237 | ||
251 | let diagnostic = Diagnostic { | 238 | primary_spans |
252 | range: location.range, | 239 | .iter() |
253 | severity, | 240 | .map(|primary_span| { |
254 | code: code.map(NumberOrString::String), | 241 | let location = map_span_to_location(&primary_span, workspace_root); |
255 | source: Some(source), | 242 | |
256 | message, | 243 | let mut message = message.clone(); |
257 | related_information: if !related_information.is_empty() { | 244 | if needs_primary_span_label { |
258 | Some(related_information) | 245 | if let Some(primary_span_label) = &primary_span.label { |
259 | } else { | 246 | write!(&mut message, "\n{}", primary_span_label).unwrap(); |
260 | None | 247 | } |
261 | }, | 248 | } |
262 | tags: if !tags.is_empty() { Some(tags) } else { None }, | 249 | |
263 | }; | 250 | // If error occurs from macro expansion, add related info pointing to |
264 | 251 | // where the error originated | |
265 | Some(MappedRustDiagnostic { location, diagnostic, fixes }) | 252 | if !is_from_macro(&primary_span.file_name) && primary_span.expansion.is_some() { |
253 | let def_loc = map_span_to_location_naive(&primary_span, workspace_root); | ||
254 | related_information.push(DiagnosticRelatedInformation { | ||
255 | location: def_loc, | ||
256 | message: "Error originated from macro here".to_string(), | ||
257 | }); | ||
258 | } | ||
259 | |||
260 | let diagnostic = Diagnostic { | ||
261 | range: location.range, | ||
262 | severity, | ||
263 | code: code.clone().map(NumberOrString::String), | ||
264 | source: Some(source.clone()), | ||
265 | message, | ||
266 | related_information: if !related_information.is_empty() { | ||
267 | Some(related_information.clone()) | ||
268 | } else { | ||
269 | None | ||
270 | }, | ||
271 | tags: if !tags.is_empty() { Some(tags.clone()) } else { None }, | ||
272 | }; | ||
273 | |||
274 | MappedRustDiagnostic { location, diagnostic, fixes: fixes.clone() } | ||
275 | }) | ||
276 | .collect() | ||
266 | } | 277 | } |
267 | 278 | ||
268 | /// Returns a `Url` object from a given path, will lowercase drive letters if present. | 279 | /// Returns a `Url` object from a given path, will lowercase drive letters if present. |