]> git.lizzy.rs Git - rust.git/commitdiff
Check for and skip dummy macro files
authorJonas Schievink <jonasschievink@gmail.com>
Thu, 1 Apr 2021 13:51:02 +0000 (15:51 +0200)
committerJonas Schievink <jonasschievink@gmail.com>
Thu, 1 Apr 2021 13:51:34 +0000 (15:51 +0200)
crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt
crates/rust-analyzer/src/diagnostics/to_proto.rs

index 206d89cfa250460c401f1e7180f6ecc136630b2e..e5f01fb33459020d5a313411e8c5dabffd094991 100644 (file)
                     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,
             ),
                 "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,
         },
index 8723c450ccb49228b3dc57ecf9a0e1a4afc17735..e2f319f6b0fd2941057b6fd0efea33f7ba176b6a 100644 (file)
@@ -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 `<macro file>` 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;