diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt | 118 | ||||
-rw-r--r-- | crates/rust-analyzer/src/diagnostics/to_proto.rs | 18 |
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. | ||
38 | fn 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 |
38 | fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { | 44 | fn 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. |
55 | fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location { | 61 | fn 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; |