about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-07-28 19:16:09 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-07-28 19:16:09 +0200
commit7d67a1b871c41fb498eeffcadfa33f1fa4c35774 (patch)
treeaec23b60b25c497d74a9f677acb5447a7d276a43
parent5e96bb459377896a85be4a192e16feca4c1d4aaf (diff)
downloadrust-7d67a1b871c41fb498eeffcadfa33f1fa4c35774.tar.gz
rust-7d67a1b871c41fb498eeffcadfa33f1fa4c35774.zip
Replace write-to-vec hack by introducing a display renderer for allocations
-rw-r--r--src/librustc_mir/interpret/memory.rs8
-rw-r--r--src/librustc_mir/util/pretty.rs50
2 files changed, 32 insertions, 26 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 0194c273f22..a9e6e324eb2 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -741,13 +741,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
             for &(_, target_id) in alloc.relocations().values() {
                 allocs_to_print.push_back(target_id);
             }
-            // This vec dance is necessary, because there is no trait
-            // that supports writing to files and to `std::fmt::Formatter` at the
-            // same time.
-            let mut v = Vec::new();
-            pretty::write_allocation(tcx, alloc, &mut v).unwrap();
-            let s = String::from_utf8(v).unwrap();
-            fmt.write_str(&s)
+            write!(fmt, "{}", pretty::display_allocation(tcx, alloc))
         }
 
         let mut allocs_to_print: VecDeque<_> = self.allocs.iter().copied().collect();
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 990bfc064c2..bed8672d911 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -588,7 +588,7 @@ pub fn write_allocations<'tcx>(
                         todo.push(id);
                     }
                 }
-                write_allocation(tcx, alloc, w)
+                write!(w, "{}", display_allocation(tcx, alloc))
             };
         write!(w, "\n{}", id)?;
         match tcx.get_global_alloc(id) {
@@ -640,24 +640,36 @@ pub fn write_allocations<'tcx>(
 /// After the hex dump, an ascii dump follows, replacing all unprintable characters (control
 /// characters or characters whose value is larger than 127) with a `.`
 /// This also prints relocations adequately.
-pub fn write_allocation<Tag: Copy + Debug, Extra>(
+pub fn display_allocation<Tag: Copy + Debug, Extra>(
     tcx: TyCtxt<'tcx>,
-    alloc: &Allocation<Tag, Extra>,
-    w: &mut dyn Write,
-) -> io::Result<()> {
-    write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?;
-    if alloc.size == Size::ZERO {
-        // We are done.
-        return write!(w, " {{}}");
+    alloc: &'a Allocation<Tag, Extra>,
+) -> RenderAllocation<'a, 'tcx, Tag, Extra> {
+    RenderAllocation { tcx, alloc }
+}
+
+#[doc(hidden)]
+pub struct RenderAllocation<'a, 'tcx, Tag, Extra> {
+    tcx: TyCtxt<'tcx>,
+    alloc: &'a Allocation<Tag, Extra>,
+}
+
+impl<Tag: Copy + Debug, Extra> std::fmt::Display for RenderAllocation<'a, 'tcx, Tag, Extra> {
+    fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let RenderAllocation { tcx, alloc } = *self;
+        write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?;
+        if alloc.size == Size::ZERO {
+            // We are done.
+            return write!(w, " {{}}");
+        }
+        // Write allocation bytes.
+        writeln!(w, " {{")?;
+        write_allocation_bytes(tcx, alloc, w, "    ")?;
+        write!(w, "}}")?;
+        Ok(())
     }
-    // Write allocation bytes.
-    writeln!(w, " {{")?;
-    write_allocation_bytes(tcx, alloc, w, "    ")?;
-    write!(w, "}}")?;
-    Ok(())
 }
 
-fn write_allocation_endline(w: &mut dyn Write, ascii: &str) -> io::Result<()> {
+fn write_allocation_endline(w: &mut dyn std::fmt::Write, ascii: &str) -> std::fmt::Result {
     for _ in 0..(BYTES_PER_LINE - ascii.chars().count()) {
         write!(w, "   ")?;
     }
@@ -669,12 +681,12 @@ const BYTES_PER_LINE: usize = 16;
 
 /// Prints the line start address and returns the new line start address.
 fn write_allocation_newline(
-    w: &mut dyn Write,
+    w: &mut dyn std::fmt::Write,
     mut line_start: Size,
     ascii: &str,
     pos_width: usize,
     prefix: &str,
-) -> io::Result<Size> {
+) -> Result<Size, std::fmt::Error> {
     write_allocation_endline(w, ascii)?;
     line_start += Size::from_bytes(BYTES_PER_LINE);
     write!(w, "{}0x{:02$x} │ ", prefix, line_start.bytes(), pos_width)?;
@@ -687,9 +699,9 @@ fn write_allocation_newline(
 fn write_allocation_bytes<Tag: Copy + Debug, Extra>(
     tcx: TyCtxt<'tcx>,
     alloc: &Allocation<Tag, Extra>,
-    w: &mut dyn Write,
+    w: &mut dyn std::fmt::Write,
     prefix: &str,
-) -> io::Result<()> {
+) -> std::fmt::Result {
     let num_lines = alloc.size.bytes_usize().saturating_sub(BYTES_PER_LINE);
     // Number of chars needed to represent all line numbers.
     let pos_width = format!("{:x}", alloc.size.bytes()).len();