Struct miri::borrow_tracker::tree_borrows::tree::LocationState
source · pub(super) struct LocationState {
initialized: bool,
permission: Permission,
latest_foreign_access: Option<AccessKind>,
}
Expand description
Data for a single location.
Fields§
§initialized: bool
A location is initialized when it is child-accessed for the first time (and the initial
retag initializes the location for the range covered by the type), and it then stays
initialized forever.
For initialized locations, “permission” is the current permission. However, for
uninitialized locations, we still need to track the “future initial permission”: this will
start out to be default_initial_perm
, but foreign accesses need to be taken into account.
Crucially however, while transitions to Disabled
would usually be UB if this location is
protected, that is not the case for uninitialized locations. Instead we just have a latent
“future initial permission” of Disabled
, causing UB only if an access is ever actually
performed.
Note that the tree root is also always initialized, as if the allocation was a write access.
permission: Permission
This pointer’s current permission / future initial permission.
latest_foreign_access: Option<AccessKind>
Strongest foreign access whose effects have already been applied to
this node and all its children since the last child access.
This is None
if the most recent access is a child access,
Some(Write)
if at least one foreign write access has been applied
since the previous child access, and Some(Read)
if at least one
foreign read and no foreign write have occurred since the last child access.
Implementations§
source§impl LocationState
impl LocationState
sourcefn new_uninit(permission: Permission) -> Self
fn new_uninit(permission: Permission) -> Self
Constructs a new initial state. It has neither been accessed, nor been subjected
to any foreign access yet.
The permission is not allowed to be Active
.
sourcefn new_init(permission: Permission) -> Self
fn new_init(permission: Permission) -> Self
Constructs a new initial state. It has not yet been subjected to any foreign access. However, it is already marked as having been accessed.
sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Check if the location has been initialized, i.e. if it has ever been accessed through a child pointer.
sourcepub fn is_initial(&self) -> bool
pub fn is_initial(&self) -> bool
Check if the state can exist as the initial permission of a pointer.
Do not confuse with is_initialized
, the two are almost orthogonal
as apart from Active
which is not initial and must be initialized,
any other permission can have an arbitrary combination of being
initial/initialized.
FIXME: when the corresponding assert
in tree_borrows/mod.rs
finally
passes and can be uncommented, remove this #[allow(dead_code)]
.
pub fn permission(&self) -> Permission
sourcefn perform_access(
&mut self,
access_kind: AccessKind,
rel_pos: AccessRelatedness,
protected: bool,
) -> Result<PermTransition, TransitionError>
fn perform_access( &mut self, access_kind: AccessKind, rel_pos: AccessRelatedness, protected: bool, ) -> Result<PermTransition, TransitionError>
Apply the effect of an access to one location, including
- applying
Permission::perform_access
to the innerPermission
, - emitting protector UB if the location is initialized,
- updating the initialized status (child accesses produce initialized locations).
fn skip_if_known_noop( &self, access_kind: AccessKind, rel_pos: AccessRelatedness, ) -> ContinueTraversal
sourcefn record_new_access(
&mut self,
access_kind: AccessKind,
rel_pos: AccessRelatedness,
)
fn record_new_access( &mut self, access_kind: AccessKind, rel_pos: AccessRelatedness, )
Records a new access, so that future access can potentially be skipped
by skip_if_known_noop
.
The invariants for this function are closely coupled to the function above:
It MUST be called on child accesses, and on foreign accesses MUST be called
when skip_if_know_noop
returns Recurse
, and MUST NOT be called otherwise.
FIXME: This optimization is wrong, and is currently disabled (by ignoring the
result returned here). Since we presumably want an optimization like this,
we should add it back. See #3864 for more information.
Trait Implementations§
source§impl Clone for LocationState
impl Clone for LocationState
source§fn clone(&self) -> LocationState
fn clone(&self) -> LocationState
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for LocationState
impl Debug for LocationState
source§impl Display for LocationState
impl Display for LocationState
source§impl Hash for LocationState
impl Hash for LocationState
source§impl PartialEq for LocationState
impl PartialEq for LocationState
impl Copy for LocationState
impl Eq for LocationState
impl StructuralPartialEq for LocationState
Auto Trait Implementations§
impl Freeze for LocationState
impl RefUnwindSafe for LocationState
impl Send for LocationState
impl Sync for LocationState
impl Unpin for LocationState
impl UnwindSafe for LocationState
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 3 bytes