about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-05-24 13:03:28 +0200
committerRalf Jung <post@ralfj.de>2019-05-24 16:11:50 +0200
commitd01ef7d9185a113fa5e089ce1ce71bb1fb6eac32 (patch)
tree813ddd05aed4c02feccccc27fb9b32c622de8edf
parent46805805abe58c287fa16963f897fd09d5d97467 (diff)
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))
-rw-r--r--src/librustc/mir/interpret/pointer.rs16
-rw-r--r--src/librustc/mir/interpret/value.rs34
2 files changed, 47 insertions, 3 deletions
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
index 59b7891b90f..356c4cc16c2 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<T: layout::HasDataLayout> 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<Tag=(),Id=AllocId> {
     pub alloc_id: Id,
@@ -80,6 +82,18 @@ pub struct Pointer<Tag=(),Id=AllocId> {
 
 static_assert_size!(Pointer, 16);
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
+    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<Id: fmt::Debug> 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<AllocId> for Pointer {
     #[inline(always)]
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 551b86390db..e3d016ff4e0 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<Tag=(), Id=AllocId> {
     /// The raw bytes of a simple value.
@@ -113,6 +113,27 @@ pub enum Scalar<Tag=(), Id=AllocId> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(Scalar, 24);
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Scalar<Tag, Id> {
+    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, "<ZST>")
+                } 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<Tag> fmt::Display for Scalar<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
@@ -412,7 +433,7 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
     }
 }
 
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
 pub enum ScalarMaybeUndef<Tag=(), Id=AllocId> {
     Scalar(Scalar<Tag, Id>),
     Undef,
@@ -425,6 +446,15 @@ impl<Tag> From<Scalar<Tag>> for ScalarMaybeUndef<Tag> {
     }
 }
 
+impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag, Id> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            ScalarMaybeUndef::Undef => write!(f, "Undef"),
+            ScalarMaybeUndef::Scalar(s) => write!(f, "{:?}", s),
+        }
+    }
+}
+
 impl<Tag> fmt::Display for ScalarMaybeUndef<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {