aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_cargo_watch/src/conv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_cargo_watch/src/conv.rs')
-rw-r--r--crates/ra_cargo_watch/src/conv.rs81
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 {
180pub(crate) fn map_rust_diagnostic_to_lsp( 180pub(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.