3 use crate::borrow_tracker::BorTag;
5 /// An item in the per-location borrow stack.
6 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
9 // An Item contains 3 bitfields:
10 // * Bits 0-61 store a BorTag
11 // * Bits 61-63 store a Permission
12 // * Bit 64 stores a flag which indicates if we have a protector
13 const TAG_MASK: u64 = u64::MAX >> 3;
14 const PERM_MASK: u64 = 0x3 << 61;
15 const PROTECTED_MASK: u64 = 0x1 << 63;
17 const PERM_SHIFT: u64 = 61;
18 const PROTECTED_SHIFT: u64 = 63;
21 pub fn new(tag: BorTag, perm: Permission, protected: bool) -> Self {
22 assert!(tag.get() <= TAG_MASK);
23 let packed_tag = tag.get();
24 let packed_perm = perm.to_bits() << PERM_SHIFT;
25 let packed_protected = u64::from(protected) << PROTECTED_SHIFT;
27 let new = Self(packed_tag | packed_perm | packed_protected);
29 debug_assert!(new.tag() == tag);
30 debug_assert!(new.perm() == perm);
31 debug_assert!(new.protected() == protected);
36 /// The pointers the permission is granted to.
37 pub fn tag(self) -> BorTag {
38 BorTag::new(self.0 & TAG_MASK).unwrap()
41 /// The permission this item grants.
42 pub fn perm(self) -> Permission {
43 Permission::from_bits((self.0 & PERM_MASK) >> PERM_SHIFT)
46 /// Whether or not there is a protector for this tag
47 pub fn protected(self) -> bool {
48 self.0 & PROTECTED_MASK > 0
51 /// Set the Permission stored in this Item
52 pub fn set_permission(&mut self, perm: Permission) {
53 // Clear the current set permission
55 // Write Permission::Disabled to the Permission bits
56 self.0 |= perm.to_bits() << PERM_SHIFT;
60 impl fmt::Debug for Item {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 write!(f, "[{:?} for {:?}]", self.perm(), self.tag())
66 /// Indicates which permission is granted (by this item to some pointers)
67 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
69 /// Grants unique mutable access.
71 /// Grants shared mutable access.
73 /// Grants shared read-only access.
75 /// Grants no access, but separates two groups of SharedReadWrite so they are not
76 /// all considered mutually compatible.
81 const UNIQUE: u64 = 0;
82 const SHARED_READ_WRITE: u64 = 1;
83 const SHARED_READ_ONLY: u64 = 2;
84 const DISABLED: u64 = 3;
86 fn to_bits(self) -> u64 {
88 Permission::Unique => Self::UNIQUE,
89 Permission::SharedReadWrite => Self::SHARED_READ_WRITE,
90 Permission::SharedReadOnly => Self::SHARED_READ_ONLY,
91 Permission::Disabled => Self::DISABLED,
95 fn from_bits(perm: u64) -> Self {
97 Self::UNIQUE => Permission::Unique,
98 Self::SHARED_READ_WRITE => Permission::SharedReadWrite,
99 Self::SHARED_READ_ONLY => Permission::SharedReadOnly,
100 Self::DISABLED => Permission::Disabled,