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..6b6f7f7a30740 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 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 {