miri/borrow_tracker/stacked_borrows/
item.rs
1use std::fmt;
2
3use crate::borrow_tracker::BorTag;
4
5#[derive(Copy, Clone, Hash, PartialEq, Eq)]
7pub struct Item(u64);
8
9const TAG_MASK: u64 = u64::MAX >> 3;
17const PERM_MASK: u64 = 0x3 << 61;
18const PROTECTED_MASK: u64 = 0x1 << 63;
19
20const PERM_SHIFT: u64 = 61;
21const PROTECTED_SHIFT: u64 = 63;
22
23impl Item {
24 pub fn new(tag: BorTag, perm: Permission, protected: bool) -> Self {
25 assert!(tag.get() <= TAG_MASK);
26 let packed_tag = tag.get();
27 let packed_perm = perm.to_bits() << PERM_SHIFT;
28 let packed_protected = u64::from(protected) << PROTECTED_SHIFT;
29
30 let new = Self(packed_tag | packed_perm | packed_protected);
31
32 debug_assert!(new.tag() == tag);
33 debug_assert!(new.perm() == perm);
34 debug_assert!(new.protected() == protected);
35
36 new
37 }
38
39 pub fn tag(self) -> BorTag {
41 BorTag::new(self.0 & TAG_MASK).unwrap()
42 }
43
44 pub fn perm(self) -> Permission {
46 Permission::from_bits((self.0 & PERM_MASK) >> PERM_SHIFT)
47 }
48
49 pub fn protected(self) -> bool {
51 self.0 & PROTECTED_MASK > 0
52 }
53
54 pub fn set_permission(&mut self, perm: Permission) {
56 self.0 &= !PERM_MASK;
58 self.0 |= perm.to_bits() << PERM_SHIFT;
60 }
61}
62
63impl fmt::Debug for Item {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 write!(f, "[{:?} for {:?}]", self.perm(), self.tag())
66 }
67}
68
69#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
71pub enum Permission {
72 Unique,
74 SharedReadWrite,
76 SharedReadOnly,
78 Disabled,
81}
82
83impl Permission {
84 const UNIQUE: u64 = 0;
85 const SHARED_READ_WRITE: u64 = 1;
86 const SHARED_READ_ONLY: u64 = 2;
87 const DISABLED: u64 = 3;
88
89 fn to_bits(self) -> u64 {
90 match self {
91 Permission::Unique => Self::UNIQUE,
92 Permission::SharedReadWrite => Self::SHARED_READ_WRITE,
93 Permission::SharedReadOnly => Self::SHARED_READ_ONLY,
94 Permission::Disabled => Self::DISABLED,
95 }
96 }
97
98 fn from_bits(perm: u64) -> Self {
99 match perm {
100 Self::UNIQUE => Permission::Unique,
101 Self::SHARED_READ_WRITE => Permission::SharedReadWrite,
102 Self::SHARED_READ_ONLY => Permission::SharedReadOnly,
103 Self::DISABLED => Permission::Disabled,
104 _ => unreachable!(),
105 }
106 }
107}