aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/diagnostics
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-04-01 14:51:02 +0100
committerJonas Schievink <[email protected]>2021-04-01 14:51:34 +0100
commit608a4653a3be3a35afce900e13d8b001fe4c5356 (patch)
treea34d530935ac15c6e8659d1045bc92a3ed73e7ba /crates/rust-analyzer/src/diagnostics
parent066330e95349f96a2481ec727bfe50f9dbca9951 (diff)
Check for and skip dummy macro files
Diffstat (limited to 'crates/rust-analyzer/src/diagnostics')
-rw-r--r--crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt118
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs18
2 files changed, 16 insertions, 120 deletions
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
@@ -22,94 +22,6 @@
22 }, 22 },
23 }, 23 },
24 severity: Some( 24 severity: Some(
25 Hint,
26 ),
27 code: Some(
28 String(
29 "E0277",
30 ),
31 ),
32 code_description: Some(
33 CodeDescription {
34 href: Url {
35 scheme: "https",
36 username: "",
37 password: None,
38 host: Some(
39 Domain(
40 "doc.rust-lang.org",
41 ),
42 ),
43 port: None,
44 path: "/error-index.html",
45 query: None,
46 fragment: Some(
47 "E0277",
48 ),
49 },
50 },
51 ),
52 source: Some(
53 "rustc",
54 ),
55 message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`",
56 related_information: Some(
57 [
58 DiagnosticRelatedInformation {
59 location: Location {
60 uri: Url {
61 scheme: "file",
62 username: "",
63 password: None,
64 host: None,
65 port: None,
66 path: "/test/%3C::core::macros::assert_eq%20macros%3E",
67 query: None,
68 fragment: None,
69 },
70 range: Range {
71 start: Position {
72 line: 6,
73 character: 30,
74 },
75 end: Position {
76 line: 6,
77 character: 32,
78 },
79 },
80 },
81 message: "Exact error occurred here",
82 },
83 ],
84 ),
85 tags: None,
86 data: None,
87 },
88 fixes: [],
89 },
90 MappedRustDiagnostic {
91 url: Url {
92 scheme: "file",
93 username: "",
94 password: None,
95 host: None,
96 port: None,
97 path: "/test/%3C::core::macros::assert_eq%20macros%3E",
98 query: None,
99 fragment: None,
100 },
101 diagnostic: Diagnostic {
102 range: Range {
103 start: Position {
104 line: 6,
105 character: 30,
106 },
107 end: Position {
108 line: 6,
109 character: 32,
110 },
111 },
112 severity: Some(
113 Error, 25 Error,
114 ), 26 ),
115 code: Some( 27 code: Some(
@@ -141,35 +53,7 @@
141 "rustc", 53 "rustc",
142 ), 54 ),
143 message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", 55 message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`",
144 related_information: Some( 56 related_information: None,
145 [
146 DiagnosticRelatedInformation {
147 location: Location {
148 uri: Url {
149 scheme: "file",
150 username: "",
151 password: None,
152 host: None,
153 port: None,
154 path: "/test/src/main.rs",
155 query: None,
156 fragment: None,
157 },
158 range: Range {
159 start: Position {
160 line: 1,
161 character: 4,
162 },
163 end: Position {
164 line: 1,
165 character: 26,
166 },
167 },
168 },
169 message: "Error originated from macro call here",
170 },
171 ],
172 ),
173 tags: None, 57 tags: None,
174 data: None, 58 data: None,
175 }, 59 },
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(
34 Some(res) 34 Some(res)
35} 35}
36 36
37/// Checks whether a file name is from macro invocation and does not refer to an actual file.
38fn is_dummy_macro_file(file_name: &str) -> bool {
39 // FIXME: current rustc does not seem to emit `<macro file>` files anymore?
40 file_name.starts_with('<') && file_name.ends_with('>')
41}
42
37/// Converts a Rust span to a LSP location 43/// Converts a Rust span to a LSP location
38fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { 44fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
39 let file_name = workspace_root.join(&span.file_name); 45 let file_name = workspace_root.join(&span.file_name);
@@ -54,14 +60,16 @@ fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location
54/// workspace into account and tries to avoid those, in case macros are involved. 60/// workspace into account and tries to avoid those, in case macros are involved.
55fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { 61fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
56 let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span)); 62 let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span));
57 for span in span_stack { 63 for span in span_stack.clone() {
58 let abs_path = workspace_root.join(&span.file_name); 64 let abs_path = workspace_root.join(&span.file_name);
59 if abs_path.starts_with(workspace_root) { 65 if !is_dummy_macro_file(&span.file_name) && abs_path.starts_with(workspace_root) {
60 return location(workspace_root, span); 66 return location(workspace_root, span);
61 } 67 }
62 } 68 }
63 69
64 location(workspace_root, span) 70 // Fall back to the outermost macro invocation if no suitable span comes up.
71 let last_span = span_stack.last().unwrap();
72 location(workspace_root, last_span)
65} 73}
66 74
67/// Converts a secondary Rust span to a LSP related information 75/// Converts a secondary Rust span to a LSP related information
@@ -255,6 +263,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
255 Some(&span.expansion.as_ref()?.span) 263 Some(&span.expansion.as_ref()?.span)
256 }); 264 });
257 for (i, span) in span_stack.enumerate() { 265 for (i, span) in span_stack.enumerate() {
266 if is_dummy_macro_file(&span.file_name) {
267 continue;
268 }
269
258 // First span is the original diagnostic, others are macro call locations that 270 // First span is the original diagnostic, others are macro call locations that
259 // generated that code. 271 // generated that code.
260 let is_in_macro_call = i != 0; 272 let is_in_macro_call = i != 0;