From 15ccad399f5b157ccf4039d71dcb9b5aeec928da Mon Sep 17 00:00:00 2001 From: Pi Lanningham Date: Tue, 5 Nov 2019 15:42:34 +0000 Subject: [PATCH] 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. --- src/librustc_passes/dead.rs | 16 +++++++++++++--- src/test/ui/span/macro-span-replacement.stderr | 7 +++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 9ad63f28a8e1..888351c61324 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 439aedb4da4d..8b65e798b6ef 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