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 { + // Return the name for a macro definition (identifier after first `!`) + pub fn span_for_macro_def_name(&self, span: Span) -> Option { 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 { + 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 { 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 {