about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPi Lanningham <pi.lanningham@gmail.com>2019-11-05 15:42:34 +0000
committerPi Lanningham <pi.lanningham@gmail.com>2019-11-05 15:42:34 +0000
commit15ccad399f5b157ccf4039d71dcb9b5aeec928da (patch)
treeb75b89aa92008ade0daae589d7f69564c4c366e2
parent7985510e37b91cab66a808ef6b3e4110e369dc9e (diff)
downloadrust-15ccad399f5b157ccf4039d71dcb9b5aeec928da.tar.gz
rust-15ccad399f5b157ccf4039d71dcb9b5aeec928da.zip
Detect if item.span is in a macro, and fall back
If item.span is part of a macro invocation, this has several downstream
implications.  To name two that were found while working on this:

 - The dead-code error gets annotated with a "in this macro invocation"
 - Some errors get canceled if they refer to remote crates

Ideally, we should annotate item.ident.span with the same macro info,
but this is a larger change (see: #66095), so for now we just fall
back to the old behavior if this item was generated by a macro.

I use span.macro_backtrace().len() to detect if it's part of a macro,
because that (among other things) is what is used by the code which
adds the "in this macro invocation" annotations mentioned above.
-rw-r--r--src/librustc_passes/dead.rs16
-rw-r--r--src/test/ui/span/macro-span-replacement.stderr7
2 files changed, 18 insertions, 5 deletions
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index 9ad63f28a8e..888351c6132 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -569,8 +569,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if self.should_warn_about_item(item) {
-            // For items that have a definition with a signature followed by a
-            // block, point only at the signature.
+            // For most items, we want to highlight its identifier
             let span = match item.kind {
                 hir::ItemKind::Fn(..) |
                 hir::ItemKind::Mod(..) |
@@ -578,7 +577,18 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
                 hir::ItemKind::Struct(..) |
                 hir::ItemKind::Union(..) |
                 hir::ItemKind::Trait(..) |
-                hir::ItemKind::Impl(..) => item.ident.span,
+                hir::ItemKind::Impl(..) => {
+                    // FIXME(66095): Because item.span is annotated with things
+                    // like a macro_backtrace, and ident.span isn't, we use the
+                    // def_span method if it's part of a macro invocation
+                    // We should probably annotate ident.span with the macro
+                    // context, but that's a larger change.
+                    if item.span.macro_backtrace().len() == 0 {
+                        item.ident.span
+                    } else {
+                        self.tcx.sess.source_map().def_span(item.span)
+                    }
+                },
                 _ => item.span,
             };
             let participle = match item.kind {
diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr
index 439aedb4da4..8b65e798b6e 100644
--- a/src/test/ui/span/macro-span-replacement.stderr
+++ b/src/test/ui/span/macro-span-replacement.stderr
@@ -1,8 +1,11 @@
 warning: struct is never constructed: `S`
-  --> $DIR/macro-span-replacement.rs:7:12
+  --> $DIR/macro-span-replacement.rs:7:14
    |
 LL |         $b $a;
-   |            ^^
+   |              ^
+...
+LL |     m!(S struct);
+   |     ------------- in this macro invocation
    |
 note: lint level defined here
   --> $DIR/macro-span-replacement.rs:3:9