about summary refs log tree commit diff
diff options
context:
space:
mode:
-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..6b6f7f7a307 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 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 {