From 7d67a1b871c41fb498eeffcadfa33f1fa4c35774 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 28 Jul 2020 19:16:09 +0200 Subject: [PATCH] Replace write-to-vec hack by introducing a display renderer for allocations --- src/librustc_mir/interpret/memory.rs | 8 +---- src/librustc_mir/util/pretty.rs | 52 +++++++++++++++++----------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 0194c273f221..a9e6e324eb23 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 990bfc064c2b..bed8672d911f 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( +pub fn display_allocation( tcx: TyCtxt<'tcx>, - alloc: &Allocation, - 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, " {{}}"); - } - // Write allocation bytes. - writeln!(w, " {{")?; - write_allocation_bytes(tcx, alloc, w, " ")?; - write!(w, "}}")?; - Ok(()) + alloc: &'a Allocation, +) -> RenderAllocation<'a, 'tcx, Tag, Extra> { + RenderAllocation { tcx, alloc } } -fn write_allocation_endline(w: &mut dyn Write, ascii: &str) -> io::Result<()> { +#[doc(hidden)] +pub struct RenderAllocation<'a, 'tcx, Tag, Extra> { + tcx: TyCtxt<'tcx>, + alloc: &'a Allocation, +} + +impl 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(()) + } +} + +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 { +) -> Result { 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( tcx: TyCtxt<'tcx>, alloc: &Allocation, - 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();