about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-01-25 20:41:44 +0000
committerbors <bors@rust-lang.org>2016-01-25 20:41:44 +0000
commiteceb96b40dedd903ddfca6df97bb1e5749b87787 (patch)
tree87751bdeafd78c1d25e462240436bf357b778942 /src/libsyntax
parent62a3a6ecc0668a9a79e8da1f199500ee74862e2e (diff)
parent616bfb6f15c377bc8850030f6239f14b8608b554 (diff)
downloadrust-eceb96b40dedd903ddfca6df97bb1e5749b87787.tar.gz
rust-eceb96b40dedd903ddfca6df97bb1e5749b87787.zip
Auto merge of #31097 - DanielJCampbell:SaveAnalysis, r=nrc
Also altered the format_args! syntax extension, and \#[derive(debug)], to maintain compatability.
r? @ nrc
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/codemap.rs25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 8d6c0df981f..432c1688536 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -858,10 +858,15 @@ impl CodeMap {
         let span_str = self.span_to_string(sp);
         let mut span_snip = self.span_to_snippet(sp)
             .unwrap_or("Snippet unavailable".to_owned());
-        if span_snip.len() > 50 {
-            span_snip.truncate(50);
+
+        // Truncate by code points - in worst case this will be more than 50 characters,
+        // but ensures at least 50 characters and respects byte boundaries.
+        let char_vec: Vec<(usize, char)> = span_snip.char_indices().collect();
+        if char_vec.len() > 50 {
+            span_snip.truncate(char_vec[49].0);
             span_snip.push_str("...");
         }
+
         output.push_str(&format!("{}{}\n{}`{}`\n", indent, span_str, indent, span_snip));
 
         if sp.expn_id == NO_EXPANSION || sp.expn_id == COMMAND_LINE_EXPN {
@@ -909,6 +914,22 @@ impl CodeMap {
         output
     }
 
+    /// Return the source span - this is either the supplied span, or the span for
+    /// the macro callsite that expanded to it.
+    pub fn source_callsite(&self, sp: Span) -> Span {
+        let mut span = sp;
+        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())) {
+                span = callsite;
+            }
+            else {
+                break;
+            }
+        }
+        span
+    }
+
     pub fn span_to_filename(&self, sp: Span) -> FileName {
         self.lookup_char_pos(sp.lo).file.name.to_string()
     }