]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_middle/src/mir/interpret/pointer.rs
New upstream version 1.64.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / mir / interpret / pointer.rs
index 26da93b9dcebc90c45bf71a188037feec25477b4..384954cbbd5f7d3939fbde8828974a46de81147c 100644 (file)
@@ -144,7 +144,7 @@ impl Provenance for AllocId {
         }
         // Print offset only if it is non-zero.
         if ptr.offset.bytes() > 0 {
-            write!(f, "+0x{:x}", ptr.offset.bytes())?;
+            write!(f, "+{:#x}", ptr.offset.bytes())?;
         }
         Ok(())
     }
@@ -159,29 +159,39 @@ impl Provenance for AllocId {
 /// Pointers are "tagged" with provenance information; typically the `AllocId` they belong to.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)]
 #[derive(HashStable)]
-pub struct Pointer<Tag = AllocId> {
-    pub(super) offset: Size, // kept private to avoid accidental misinterpretation (meaning depends on `Tag` type)
-    pub provenance: Tag,
+pub struct Pointer<Prov = AllocId> {
+    pub(super) offset: Size, // kept private to avoid accidental misinterpretation (meaning depends on `Prov` type)
+    pub provenance: Prov,
 }
 
 static_assert_size!(Pointer, 16);
-// `Option<Tag>` pointers are also passed around quite a bit
+// `Option<Prov>` pointers are also passed around quite a bit
 // (but not stored in permanent machine state).
 static_assert_size!(Pointer<Option<AllocId>>, 16);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
 // all the Miri types.
-impl<Tag: Provenance> fmt::Debug for Pointer<Tag> {
+impl<Prov: Provenance> fmt::Debug for Pointer<Prov> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         Provenance::fmt(self, f)
     }
 }
 
-impl<Tag: Provenance> fmt::Debug for Pointer<Option<Tag>> {
+impl<Prov: Provenance> fmt::Debug for Pointer<Option<Prov>> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.provenance {
-            Some(tag) => Provenance::fmt(&Pointer::new(tag, self.offset), f),
-            None => write!(f, "0x{:x}", self.offset.bytes()),
+            Some(prov) => Provenance::fmt(&Pointer::new(prov, self.offset), f),
+            None => write!(f, "{:#x}[noalloc]", self.offset.bytes()),
+        }
+    }
+}
+
+impl<Prov: Provenance> fmt::Display for Pointer<Option<Prov>> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if self.provenance.is_none() && self.offset.bytes() == 0 {
+            write!(f, "null pointer")
+        } else {
+            fmt::Debug::fmt(self, f)
         }
     }
 }
@@ -194,59 +204,64 @@ impl From<AllocId> for Pointer {
     }
 }
 
-impl<Tag> From<Pointer<Tag>> for Pointer<Option<Tag>> {
+impl<Prov> From<Pointer<Prov>> for Pointer<Option<Prov>> {
     #[inline(always)]
-    fn from(ptr: Pointer<Tag>) -> Self {
-        let (tag, offset) = ptr.into_parts();
-        Pointer::new(Some(tag), offset)
+    fn from(ptr: Pointer<Prov>) -> Self {
+        let (prov, offset) = ptr.into_parts();
+        Pointer::new(Some(prov), offset)
     }
 }
 
-impl<Tag> Pointer<Option<Tag>> {
-    /// Convert this pointer that *might* have a tag into a pointer that *definitely* has a tag, or
-    /// an absolute address.
+impl<Prov> Pointer<Option<Prov>> {
+    /// Convert this pointer that *might* have a provenance into a pointer that *definitely* has a
+    /// provenance, or an absolute address.
     ///
     /// This is rarely what you want; call `ptr_try_get_alloc_id` instead.
-    pub fn into_pointer_or_addr(self) -> Result<Pointer<Tag>, Size> {
+    pub fn into_pointer_or_addr(self) -> Result<Pointer<Prov>, Size> {
         match self.provenance {
-            Some(tag) => Ok(Pointer::new(tag, self.offset)),
+            Some(prov) => Ok(Pointer::new(prov, self.offset)),
             None => Err(self.offset),
         }
     }
 
     /// Returns the absolute address the pointer points to.
-    /// Only works if Tag::OFFSET_IS_ADDR is true!
+    /// Only works if Prov::OFFSET_IS_ADDR is true!
     pub fn addr(self) -> Size
     where
-        Tag: Provenance,
+        Prov: Provenance,
     {
-        assert!(Tag::OFFSET_IS_ADDR);
+        assert!(Prov::OFFSET_IS_ADDR);
         self.offset
     }
 }
 
-impl<Tag> Pointer<Option<Tag>> {
+impl<Prov> Pointer<Option<Prov>> {
+    #[inline(always)]
+    pub fn from_addr(addr: u64) -> Self {
+        Pointer { provenance: None, offset: Size::from_bytes(addr) }
+    }
+
     #[inline(always)]
     pub fn null() -> Self {
-        Pointer { provenance: None, offset: Size::ZERO }
+        Pointer::from_addr(0)
     }
 }
 
-impl<'tcx, Tag> Pointer<Tag> {
+impl<'tcx, Prov> Pointer<Prov> {
     #[inline(always)]
-    pub fn new(provenance: Tag, offset: Size) -> Self {
+    pub fn new(provenance: Prov, offset: Size) -> Self {
         Pointer { provenance, offset }
     }
 
-    /// Obtain the constituents of this pointer. Not that the meaning of the offset depends on the type `Tag`!
+    /// Obtain the constituents of this pointer. Not that the meaning of the offset depends on the type `Prov`!
     /// This function must only be used in the implementation of `Machine::ptr_get_alloc`,
     /// and when a `Pointer` is taken apart to be stored efficiently in an `Allocation`.
     #[inline(always)]
-    pub fn into_parts(self) -> (Tag, Size) {
+    pub fn into_parts(self) -> (Prov, Size) {
         (self.provenance, self.offset)
     }
 
-    pub fn map_provenance(self, f: impl FnOnce(Tag) -> Tag) -> Self {
+    pub fn map_provenance(self, f: impl FnOnce(Prov) -> Prov) -> Self {
         Pointer { provenance: f(self.provenance), ..self }
     }