Skip to content

Changed macro spans in CSVs to point to the macro name, fixed nested spans #31382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/librustc_trans/save/dump_csv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions src/librustc_trans/save/span_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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.
///
Expand Down
21 changes: 20 additions & 1 deletion src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down