source_map: &Option<Lrc<SourceMapperDyn>>,
span: &mut MultiSpan,
always_backtrace: bool) -> bool {
- let mut spans_updated = false;
+ let sm = match source_map {
+ Some(ref sm) => sm,
+ None => return false,
+ };
- if let Some(ref sm) = source_map {
- let mut before_after: Vec<(Span, Span)> = vec![];
- let mut new_labels: Vec<(Span, String)> = vec![];
+ let mut before_after: Vec<(Span, Span)> = vec![];
+ let mut new_labels: Vec<(Span, String)> = vec![];
- // First, find all the spans in <*macros> and point instead at their use site
- for sp in span.primary_spans() {
- if sp.is_dummy() {
+ // First, find all the spans in <*macros> and point instead at their use site
+ for sp in span.primary_spans() {
+ if sp.is_dummy() {
+ continue;
+ }
+ let call_sp = sm.call_span_if_macro(*sp);
+ if call_sp != *sp && !always_backtrace {
+ before_after.push((*sp, call_sp));
+ }
+ let backtrace_len = sp.macro_backtrace().len();
+ for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
+ // Only show macro locations that are local
+ // and display them like a span_note
+ if trace.def_site_span.is_dummy() {
continue;
}
- let call_sp = sm.call_span_if_macro(*sp);
- if call_sp != *sp && !always_backtrace {
- before_after.push((*sp, call_sp));
+ if always_backtrace {
+ new_labels.push((trace.def_site_span,
+ format!("in this expansion of `{}`{}",
+ trace.macro_decl_name,
+ if backtrace_len > 2 {
+ // if backtrace_len == 1 it'll be pointed
+ // at by "in this macro invocation"
+ format!(" (#{})", i + 1)
+ } else {
+ String::new()
+ })));
}
- let backtrace_len = sp.macro_backtrace().len();
- for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
- // Only show macro locations that are local
- // and display them like a span_note
- if trace.def_site_span.is_dummy() {
- continue;
- }
- if always_backtrace {
- new_labels.push((trace.def_site_span,
- format!("in this expansion of `{}`{}",
- trace.macro_decl_name,
- if backtrace_len > 2 {
- // if backtrace_len == 1 it'll be pointed
- // at by "in this macro invocation"
- format!(" (#{})", i + 1)
- } else {
- String::new()
- })));
- }
- // Check to make sure we're not in any <*macros>
- if !sm.span_to_filename(trace.def_site_span).is_macros() &&
- !trace.macro_decl_name.starts_with("desugaring of ") &&
- !trace.macro_decl_name.starts_with("#[") ||
- always_backtrace {
- new_labels.push((trace.call_site,
- format!("in this macro invocation{}",
- if backtrace_len > 2 && always_backtrace {
- // only specify order when the macro
- // backtrace is multiple levels deep
- format!(" (#{})", i + 1)
- } else {
- String::new()
- })));
- if !always_backtrace {
- break;
- }
+ // Check to make sure we're not in any <*macros>
+ if !sm.span_to_filename(trace.def_site_span).is_macros() &&
+ !trace.macro_decl_name.starts_with("desugaring of ") &&
+ !trace.macro_decl_name.starts_with("#[") ||
+ always_backtrace {
+ new_labels.push((trace.call_site,
+ format!("in this macro invocation{}",
+ if backtrace_len > 2 && always_backtrace {
+ // only specify order when the macro
+ // backtrace is multiple levels deep
+ format!(" (#{})", i + 1)
+ } else {
+ String::new()
+ })));
+ if !always_backtrace {
+ break;
}
}
}
- for (label_span, label_text) in new_labels {
- span.push_span_label(label_span, label_text);
+ }
+ for (label_span, label_text) in new_labels {
+ span.push_span_label(label_span, label_text);
+ }
+ for sp_label in span.span_labels() {
+ if sp_label.span.is_dummy() {
+ continue;
}
- for sp_label in span.span_labels() {
- if sp_label.span.is_dummy() {
- continue;
- }
- if sm.span_to_filename(sp_label.span.clone()).is_macros() &&
- !always_backtrace
- {
- let v = sp_label.span.macro_backtrace();
- if let Some(use_site) = v.last() {
- before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
- }
+ if sm.span_to_filename(sp_label.span.clone()).is_macros() &&
+ !always_backtrace
+ {
+ let v = sp_label.span.macro_backtrace();
+ if let Some(use_site) = v.last() {
+ before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
}
}
- // After we have them, make sure we replace these 'bad' def sites with their use sites
- for (before, after) in before_after {
- span.replace(before, after);
- spans_updated = true;
- }
+ }
+ // After we have them, make sure we replace these 'bad' def sites with their use sites
+ let spans_updated = !before_after.is_empty();
+ for (before, after) in before_after {
+ span.replace(before, after);
}
spans_updated