Skip to content

Commit 608a465

Browse files
Check for and skip dummy macro files
1 parent 066330e commit 608a465

File tree

2 files changed

+16
-120
lines changed

2 files changed

+16
-120
lines changed

crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt

Lines changed: 1 addition & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -21,94 +21,6 @@
2121
character: 26,
2222
},
2323
},
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-
},
11224
severity: Some(
11325
Error,
11426
),
@@ -141,35 +53,7 @@
14153
"rustc",
14254
),
14355
message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`",
144-
related_information: Some(
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-
),
56+
related_information: None,
17357
tags: None,
17458
data: None,
17559
},

crates/rust-analyzer/src/diagnostics/to_proto.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ fn diagnostic_severity(
3434
Some(res)
3535
}
3636

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+
3743
/// Converts a Rust span to a LSP location
3844
fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
3945
let file_name = workspace_root.join(&span.file_name);
@@ -54,14 +60,16 @@ fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location
5460
/// workspace into account and tries to avoid those, in case macros are involved.
5561
fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
5662
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() {
5864
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) {
6066
return location(workspace_root, span);
6167
}
6268
}
6369

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)
6573
}
6674

6775
/// Converts a secondary Rust span to a LSP related information
@@ -255,6 +263,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
255263
Some(&span.expansion.as_ref()?.span)
256264
});
257265
for (i, span) in span_stack.enumerate() {
266+
if is_dummy_macro_file(&span.file_name) {
267+
continue;
268+
}
269+
258270
// First span is the original diagnostic, others are macro call locations that
259271
// generated that code.
260272
let is_in_macro_call = i != 0;

0 commit comments

Comments
 (0)