about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-01-21 01:46:53 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-01-26 17:18:55 +0200
commit6980f82c0d152446506fee4d4a45d8afdf4ad9a4 (patch)
tree105db4bbe1eb9f95251c1414f926a3e3f36602cb
parent75284f8cbdfa17046156528dc3aa5303f8752f97 (diff)
downloadrust-6980f82c0d152446506fee4d4a45d8afdf4ad9a4.tar.gz
rust-6980f82c0d152446506fee4d4a45d8afdf4ad9a4.zip
rustc_span: return an impl Iterator instead of a Vec from macro_backtrace.
-rw-r--r--src/librustc_errors/emitter.rs8
-rw-r--r--src/librustc_errors/json.rs4
-rw-r--r--src/librustc_span/lib.rs33
-rw-r--r--src/librustc_span/source_map.rs3
4 files changed, 25 insertions, 23 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 49c8be28292..f9e23e96fa8 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -343,8 +343,9 @@ pub trait Emitter {
             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() {
+            let macro_backtrace: Vec<_> = sp.macro_backtrace().collect();
+            let backtrace_len = macro_backtrace.len();
+            for (i, trace) in macro_backtrace.iter().rev().enumerate() {
                 // Only show macro locations that are local
                 // and display them like a span_note
                 if trace.def_site.is_dummy() {
@@ -398,8 +399,7 @@ pub trait Emitter {
                 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() {
+                if let Some(use_site) = sp_label.span.macro_backtrace().last() {
                     before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
                 }
             }
diff --git a/src/librustc_errors/json.rs b/src/librustc_errors/json.rs
index 21be9527b6c..3ddf9b09893 100644
--- a/src/librustc_errors/json.rs
+++ b/src/librustc_errors/json.rs
@@ -309,7 +309,7 @@ impl DiagnosticSpan {
         // backtrace ourselves, but the `macro_backtrace` helper makes
         // some decision, such as dropping some frames, and I don't
         // want to duplicate that logic here.
-        let backtrace = span.macro_backtrace().into_iter();
+        let backtrace = span.macro_backtrace();
         DiagnosticSpan::from_span_full(span, is_primary, label, suggestion, backtrace, je)
     }
 
@@ -318,7 +318,7 @@ impl DiagnosticSpan {
         is_primary: bool,
         label: Option<String>,
         suggestion: Option<(&String, Applicability)>,
-        mut backtrace: vec::IntoIter<ExpnData>,
+        mut backtrace: impl Iterator<Item = ExpnData>,
         je: &JsonEmitter,
     ) -> DiagnosticSpan {
         let start = je.sm.lookup_char_pos(span.lo());
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 3f23eb15829..413bd77daae 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -445,23 +445,26 @@ impl Span {
         self.ctxt().outer_expn_data().allow_internal_unsafe
     }
 
-    pub fn macro_backtrace(mut self) -> Vec<ExpnData> {
+    pub fn macro_backtrace(mut self) -> impl Iterator<Item = ExpnData> {
         let mut prev_span = DUMMY_SP;
-        let mut result = vec![];
-        loop {
-            let expn_data = self.ctxt().outer_expn_data();
-            if expn_data.is_root() {
-                break;
-            }
-            // Don't print recursive invocations.
-            if !expn_data.call_site.source_equal(&prev_span) {
-                result.push(expn_data.clone());
-            }
+        std::iter::from_fn(move || {
+            loop {
+                let expn_data = self.ctxt().outer_expn_data();
+                if expn_data.is_root() {
+                    return None;
+                }
 
-            prev_span = self;
-            self = expn_data.call_site;
-        }
-        result
+                let is_recursive = expn_data.call_site.source_equal(&prev_span);
+
+                prev_span = self;
+                self = expn_data.call_site;
+
+                // Don't print recursive invocations.
+                if !is_recursive {
+                    return Some(expn_data);
+                }
+            }
+        })
     }
 
     /// Returns a `Span` that would enclose both `self` and `end`.
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index e0b93b9ce25..c250df43a27 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -947,8 +947,7 @@ impl SourceMap {
     }
     pub fn call_span_if_macro(&self, sp: Span) -> Span {
         if self.span_to_filename(sp.clone()).is_macros() {
-            let v = sp.macro_backtrace();
-            if let Some(use_site) = v.last() {
+            if let Some(use_site) = sp.macro_backtrace().last() {
                 return use_site.call_site;
             }
         }