about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-02-04 15:44:35 +0000
committerbors <bors@rust-lang.org>2016-02-04 15:44:35 +0000
commitf01b85b1034889888be65d2208640ac926a42d36 (patch)
treee70747bfffb0d6092ec42577382e5d83a4dc5580
parente64ca8cd59c859e8ae4a8063c3f3146a05be01d1 (diff)
parentb361b7f1a5bd1d7a0a66b908a65c1fdfe65ae3bf (diff)
downloadrust-f01b85b1034889888be65d2208640ac926a42d36.tar.gz
rust-f01b85b1034889888be65d2208640ac926a42d36.zip
Auto merge of #31382 - DanielJCampbell:SaveSpans, r=nrc
r? @nrc
-rw-r--r--src/librustc_trans/save/dump_csv.rs14
-rw-r--r--src/librustc_trans/save/span_utils.rs24
-rw-r--r--src/libsyntax/codemap.rs21
3 files changed, 51 insertions, 8 deletions
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 2b866eeaa9f..25c30f2476d 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -847,13 +847,17 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         if !self.mac_defs.contains(&data.callee_span)
             && !data.imported {
             self.mac_defs.insert(data.callee_span);
-            self.fmt.macro_str(data.callee_span, data.callee_span,
-                               data.name.clone(), qualname.clone());
+            if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) {
+                self.fmt.macro_str(data.callee_span, sub_span,
+                                   data.name.clone(), qualname.clone());
+            }
         }
         if !self.mac_uses.contains(&data.span) {
-             self.mac_uses.insert(data.span);
-             self.fmt.macro_use_str(data.span, data.span, data.name,
-                                   qualname, data.scope);
+            self.mac_uses.insert(data.span);
+            if let Some(sub_span) = self.span.span_for_macro_use_name(data.span) {
+                self.fmt.macro_use_str(data.span, sub_span, data.name,
+                                       qualname, data.scope);
+            }
         }
     }
 }
diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs
index 95c1d7bd031..2a5c61f4e9d 100644
--- a/src/librustc_trans/save/span_utils.rs
+++ b/src/librustc_trans/save/span_utils.rs
@@ -378,8 +378,8 @@ impl<'a> SpanUtils<'a> {
         }
     }
 
-    // Given a macro_rules definition span, return the span of the macro's name.
-    pub fn span_for_macro_name(&self, span: Span) -> Option<Span> {
+    // Return the name for a macro definition (identifier after first `!`)
+    pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
         let mut toks = self.retokenise_span(span);
         loop {
             let ts = toks.real_token();
@@ -397,6 +397,26 @@ impl<'a> SpanUtils<'a> {
         }
     }
 
+    // Return the name for a macro use (identifier before first `!`).
+    pub fn span_for_macro_use_name(&self, span:Span) -> Option<Span> {
+        let mut toks = self.retokenise_span(span);
+        let mut prev = toks.real_token();
+        loop {
+            if prev.tok == token::Eof {
+                return None;
+            }
+            let ts = toks.real_token();
+            if ts.tok == token::Not {
+                if prev.tok.is_ident() {
+                    return self.make_sub_span(span, Some(prev.sp));
+                } else {
+                    return None;
+                }
+            }
+            prev = ts;
+        }
+    }
+
     /// Return true if the span is generated code, and
     /// it is not a subspan of the root callsite.
     ///
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 9da5e1e3881..74302e2f6a0 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -1052,9 +1052,18 @@ impl CodeMap {
     /// the macro callsite that expanded to it.
     pub fn source_callsite(&self, sp: Span) -> Span {
         let mut span = sp;
+        // Special case - if a macro is parsed as an argument to another macro, the source
+        // callsite is the first callsite, which is also source-equivalent to the span.
+        let mut first = true;
         while span.expn_id != NO_EXPANSION && span.expn_id != COMMAND_LINE_EXPN {
             if let Some(callsite) = self.with_expn_info(span.expn_id,
                                                |ei| ei.map(|ei| ei.call_site.clone())) {
+                if first && span.source_equal(&callsite) {
+                    if self.lookup_char_pos(span.lo).file.is_real_file() {
+                        return Span { expn_id: NO_EXPANSION, .. span };
+                    }
+                }
+                first = false;
                 span = callsite;
             }
             else {
@@ -1071,10 +1080,20 @@ impl CodeMap {
     /// corresponding to the source callsite.
     pub fn source_callee(&self, sp: Span) -> Option<NameAndSpan> {
         let mut span = sp;
+        // Special case - if a macro is parsed as an argument to another macro, the source
+        // callsite is source-equivalent to the span, and the source callee is the first callee.
+        let mut first = true;
         while let Some(callsite) = self.with_expn_info(span.expn_id,
                                             |ei| ei.map(|ei| ei.call_site.clone())) {
+            if first && span.source_equal(&callsite) {
+                if self.lookup_char_pos(span.lo).file.is_real_file() {
+                    return self.with_expn_info(span.expn_id,
+                                               |ei| ei.map(|ei| ei.callee.clone()));
+                }
+            }
+            first = false;
             if let Some(_) = self.with_expn_info(callsite.expn_id,
-                                                |ei| ei.map(|ei| ei.call_site.clone())) {
+                                                 |ei| ei.map(|ei| ei.call_site.clone())) {
                 span = callsite;
             }
             else {