From 608a4653a3be3a35afce900e13d8b001fe4c5356 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 1 Apr 2021 15:51:02 +0200 Subject: Check for and skip dummy macro files --- .../test_data/handles_macro_location.txt | 118 +-------------------- crates/rust-analyzer/src/diagnostics/to_proto.rs | 18 +++- 2 files changed, 16 insertions(+), 120 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt index 206d89cfa..e5f01fb33 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt @@ -21,94 +21,6 @@ character: 26, }, }, - severity: Some( - Hint, - ), - code: Some( - String( - "E0277", - ), - ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", - ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0277", - ), - }, - }, - ), - source: Some( - "rustc", - ), - message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", - related_information: Some( - [ - DiagnosticRelatedInformation { - location: Location { - uri: Url { - scheme: "file", - username: "", - password: None, - host: None, - port: None, - path: "/test/%3C::core::macros::assert_eq%20macros%3E", - query: None, - fragment: None, - }, - range: Range { - start: Position { - line: 6, - character: 30, - }, - end: Position { - line: 6, - character: 32, - }, - }, - }, - message: "Exact error occurred here", - }, - ], - ), - tags: None, - data: None, - }, - fixes: [], - }, - MappedRustDiagnostic { - url: Url { - scheme: "file", - username: "", - password: None, - host: None, - port: None, - path: "/test/%3C::core::macros::assert_eq%20macros%3E", - query: None, - fragment: None, - }, - diagnostic: Diagnostic { - range: Range { - start: Position { - line: 6, - character: 30, - }, - end: Position { - line: 6, - character: 32, - }, - }, severity: Some( Error, ), @@ -141,35 +53,7 @@ "rustc", ), message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", - related_information: Some( - [ - DiagnosticRelatedInformation { - location: Location { - uri: Url { - scheme: "file", - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, - range: Range { - start: Position { - line: 1, - character: 4, - }, - end: Position { - line: 1, - character: 26, - }, - }, - }, - message: "Error originated from macro call here", - }, - ], - ), + related_information: None, tags: None, data: None, }, diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index 8723c450c..e2f319f6b 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -34,6 +34,12 @@ fn diagnostic_severity( Some(res) } +/// Checks whether a file name is from macro invocation and does not refer to an actual file. +fn is_dummy_macro_file(file_name: &str) -> bool { + // FIXME: current rustc does not seem to emit `` files anymore? + file_name.starts_with('<') && file_name.ends_with('>') +} + /// Converts a Rust span to a LSP location fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { let file_name = workspace_root.join(&span.file_name); @@ -54,14 +60,16 @@ fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location /// workspace into account and tries to avoid those, in case macros are involved. fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span)); - for span in span_stack { + for span in span_stack.clone() { let abs_path = workspace_root.join(&span.file_name); - if abs_path.starts_with(workspace_root) { + if !is_dummy_macro_file(&span.file_name) && abs_path.starts_with(workspace_root) { return location(workspace_root, span); } } - location(workspace_root, span) + // Fall back to the outermost macro invocation if no suitable span comes up. + let last_span = span_stack.last().unwrap(); + location(workspace_root, last_span) } /// Converts a secondary Rust span to a LSP related information @@ -255,6 +263,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp( Some(&span.expansion.as_ref()?.span) }); for (i, span) in span_stack.enumerate() { + if is_dummy_macro_file(&span.file_name) { + continue; + } + // First span is the original diagnostic, others are macro call locations that // generated that code. let is_in_macro_call = i != 0; -- cgit v1.2.3