From d01ef7d9185a113fa5e089ce1ce71bb1fb6eac32 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 24 May 2019 13:03:28 +0200 Subject: [PATCH 1/2] improve debug-printing of scalars Before: Immediate(ScalarMaybeUndef(Scalar(Ptr(Pointer { alloc_id: AllocId(3401), offset: Size { raw: 4 }, tag: Tagged(7723) })))) After: Immediate(Scalar(AllocId(3401).0x4[<7723>])) Before: Immediate(ScalarMaybeUndef(Scalar(Bits { size: 8, bits: 10 }))) After: Immediate(Scalar(0x000000000000000A)) Before: Immediate(ScalarMaybeUndef(Scalar(Bits { size: 1, bits: 1 }))) After: Immediate(Scalar(0x01)) --- src/librustc/mir/interpret/pointer.rs | 16 ++++++++++++- src/librustc/mir/interpret/value.rs | 34 +++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 59b7891b90fde..356c4cc16c23c 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -1,3 +1,5 @@ +use std::fmt; + use crate::mir; use crate::ty::layout::{self, HasDataLayout, Size}; use rustc_macros::HashStable; @@ -70,7 +72,7 @@ impl PointerArithmetic for T {} /// /// Pointer is also generic over the `Tag` associated with each pointer, /// which is used to do provenance tracking during execution. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash, HashStable)] pub struct Pointer { pub alloc_id: Id, @@ -80,6 +82,18 @@ pub struct Pointer { static_assert_size!(Pointer, 16); +impl fmt::Debug for Pointer { + default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}.{:#x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag) + } +} +// Specialization for no tag +impl fmt::Debug for Pointer<(), Id> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}.{:#x}", self.alloc_id, self.offset.bytes()) + } +} + /// Produces a `Pointer` which points to the beginning of the Allocation impl From for Pointer { #[inline(always)] diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 551b86390db4c..e3d016ff4e03e 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -93,7 +93,7 @@ impl<'tcx> ConstValue<'tcx> { /// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes /// of a simple value or a pointer into another `Allocation` -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash, HashStable)] pub enum Scalar { /// The raw bytes of a simple value. @@ -113,6 +113,27 @@ pub enum Scalar { #[cfg(target_arch = "x86_64")] static_assert_size!(Scalar, 24); +impl fmt::Debug for Scalar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Scalar::Ptr(ptr) => + write!(f, "{:?}", ptr), + &Scalar::Bits { bits, size } => { + if size == 0 { + assert_eq!(bits, 0, "ZST value must be 0"); + write!(f, "") + } else { + assert_eq!(truncate(bits, Size::from_bytes(size as u64)), bits, + "Scalar value {:#x} exceeds size of {} bytes", bits, size); + // Format as hex number wide enough to fit any value of the given `size`. + // So e.g. bits=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014". + write!(f, "0x{:>0width$x}", bits, width=(size*2) as usize) + } + } + } + } +} + impl fmt::Display for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -412,7 +433,7 @@ impl From> for Scalar { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)] +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)] pub enum ScalarMaybeUndef { Scalar(Scalar), Undef, @@ -425,6 +446,15 @@ impl From> for ScalarMaybeUndef { } } +impl fmt::Debug for ScalarMaybeUndef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ScalarMaybeUndef::Undef => write!(f, "Undef"), + ScalarMaybeUndef::Scalar(s) => write!(f, "{:?}", s), + } + } +} + impl fmt::Display for ScalarMaybeUndef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { From a90cdcca7eb189901a666cbee194f08719e10b94 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 24 May 2019 16:44:52 +0200 Subject: [PATCH 2/2] this is for tidy --- src/librustc/mir/interpret/value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index e3d016ff4e03e..6b6f7f7a30740 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -126,7 +126,7 @@ impl fmt::Debug for Scalar { assert_eq!(truncate(bits, Size::from_bytes(size as u64)), bits, "Scalar value {:#x} exceeds size of {} bytes", bits, size); // Format as hex number wide enough to fit any value of the given `size`. - // So e.g. bits=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014". + // So bits=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014". write!(f, "0x{:>0width$x}", bits, width=(size*2) as usize) } }