pub struct CursorMut<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> {
pub list: &'a mut LinkedList<M>,
pub current: Option<ReprPtr<MetaSlotStorage, Link<M>>>,
}Expand description
A cursor that can mutate the linked list links.
The cursor points to either a frame or the “ghost” non-element. It points to the “ghost” non-element when the cursor surpasses the back of the list.
Fields§
§list: &'a mut LinkedList<M>§current: Option<ReprPtr<MetaSlotStorage, Link<M>>>Implementations§
Source§impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorMut<'a, M>
impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorMut<'a, M>
Sourcepub exec fn move_next(&mut self)
pub exec fn move_next(&mut self)
Tracked(owner): Tracked<CursorOwner<M>>,
Tracked(regions): Tracked<&MetaRegionOwners>,requiresowner.wf_with_region(*regions),old(self).wf_region(owner, *regions),ensuresowner.move_next_owner_spec()@ == owner@.move_next_spec(),owner.move_next_owner_spec().wf_with_region(*regions),final(self).wf_region(owner.move_next_owner_spec(), *regions),Moves the cursor to the next frame towards the back.
If the cursor is pointing to the “ghost” non-element then this will
move it to the first element of the LinkedList. If it is pointing
to the last element of the LinkedList then this will move it to the
“ghost” non-element.
Sourcepub exec fn move_prev(&mut self)
pub exec fn move_prev(&mut self)
Tracked(owner): Tracked<CursorOwner<M>>,
Tracked(regions): Tracked<&MetaRegionOwners>,requiresowner.wf_with_region(*regions),old(self).wf_region(owner, *regions),ensuresowner.move_prev_owner_spec()@ == owner@.move_prev_spec(),owner.move_prev_owner_spec().wf_with_region(*regions),final(self).wf_region(owner.move_prev_owner_spec(), *regions),Moves the cursor to the previous frame towards the front.
If the cursor is pointing to the “ghost” non-element then this will
move it to the last element of the LinkedList. If it is pointing
to the first element of the LinkedList then this will move it to the
“ghost” non-element.
Sourcepub exec fn current_meta<'b>(&'b mut self) -> res : Option<&'b mut M>
pub exec fn current_meta<'b>(&'b mut self) -> res : Option<&'b mut M>
Tracked(owner): Tracked<&'b mut CursorOwner<M>>,
Tracked(regions): Tracked<&'b mut MetaRegionOwners>,requiresold(self).wf_region(*old(owner), *old(regions)),old(owner).wf_with_region(*old(regions)),old(regions).inv(),ensuresfinal(owner).index == old(owner).index,final(owner).list_own.list == old(owner).list_own.list,final(owner).list_own.list_id == old(owner).list_own.list_id,*final(self) == *old(self),res.is_some() == (0 <= final(owner).index < final(owner).length()),final(regions).slots.dom() == old(regions).slots.dom(),final(regions).slot_owners.dom() == old(regions).slot_owners.dom(),Gets the mutable reference to the current frame’s metadata.
§Verified Properties
§Preconditions
The cursor must be well-formed with respect to the tracked CursorOwner.
§Postconditions
If the cursor is on an element, returns Some(&mut meta) borrowing the
current link’s metadata. The cursor state and list shape are otherwise
unchanged; the current metadata permission remains borrowed while the
returned reference is live.
§Safety
The &mut self guarantees exclusive access to the cursor; the tracked
CursorOwner guarantees the perm for the current link is live.
Sourcepub exec fn take_current(
&mut self,
) -> res : Option<(UniqueFrame<Link<M>>, Tracked<UniqueFrameOwner<Link<M>>>)>
pub exec fn take_current( &mut self, ) -> res : Option<(UniqueFrame<Link<M>>, Tracked<UniqueFrameOwner<Link<M>>>)>
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut CursorOwner<M>>,requiresold(self).wf_region(*old(owner), *old(regions)),old(owner).wf_with_region(*old(regions)),old(regions).inv(),ensuresold(owner).length() == 0 ==> res.is_none(),old(self).current.is_some() ==> res.is_some(),res.is_some() ==> (res->0).1@.meta_own@ == old(owner).list_own.list[old(owner).index]@,res.is_some() ==> final(owner)@ == old(owner)@.remove(),res.is_some() ==> (res->0).0.frame_link_inv((res->0).1@, *final(regions)),res.is_some() ==> final(owner).wf_with_region(*final(regions)),res.is_some() ==> final(self).wf_region(*final(owner), *final(regions)),res.is_none() ==> *final(owner) == *old(owner),final(regions).inv(),res.is_some() ==> final(owner).index == old(owner).index,res.is_some()
==> final(owner).list_own.list == old(owner).list_own.list.remove(old(owner).index),final(owner).list_own.list_id == old(owner).list_own.list_id,res.is_some()
==> {
let paddr = old(self).current->0.addr();
let idx = meta_to_index(paddr);
&&& final(regions).slots.dom() == old(regions).slots.dom()
&&& final(regions).ref_count(idx) == REF_COUNT_UNIQUE
&&& final(regions).slot_owners[idx].in_list_perm.value() == 0
&&& (res->0).0.tracked_metadata_perm@->0.storage_perm.is_init()
&&& (res->0).0.tracked_metadata_perm@->0.vtable_ptr_perm.is_init()
&&& final(regions).slot_owners[idx].slot_vaddr == index_to_meta(idx)
&&& final(regions).slot_owners[idx].paths_in_pt
== old(regions).slot_owners[idx].paths_in_pt
},res.is_some()
==> forall |j: int| {
j != meta_to_index(old(self).current->0.addr())
==> {
&&& final(regions).slot_owners[j].usage
== old(regions).slot_owners[j].usage
&&& final(regions).slot_owners[j].slot_vaddr
== old(regions).slot_owners[j].slot_vaddr
&&& final(regions).slot_owners[j].paths_in_pt
== old(regions).slot_owners[j].paths_in_pt
}
},res.is_none() ==> *final(regions) == *old(regions),res.is_some() ==> (res->0).0.inv(),res.is_some() ==> (res->0).0.wf((res->0).1@),res.is_some() ==> (res->0).1@.inv(),res.is_some() ==> (res->0).0.wf_with_region((res->0).1@, *final(regions)),res.is_some() ==> (res->0).1@.slot_index == meta_to_index(old(self).current->0.addr()),res.is_some() ==> (res->0).0.ptr.addr() == old(self).current->0.addr(),Takes the current pointing frame out of the linked list.
If successful, the frame is returned and the cursor is moved to the next frame. If the cursor is pointing to the back of the list then it is moved to the “ghost” non-element.
§Verified Properties
§Preconditions
The cursor must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects. The list must be non-empty, so that the current frame is valid.
§Postconditions
The current frame is removed from the list, and the cursor is moved to the next frame. The list invariants are preserved.
§Safety
This function calls from_raw on the frame, but we guarantee that the frame is forgotten
if it is in the list. So, double-free will not occur. All loads and stores are through track
tracked permissions, so there are no illegal memory accesses. No data races are possible.
Sourcepub exec fn insert_before(&mut self, frame: UniqueFrame<Link<M>>)
pub exec fn insert_before(&mut self, frame: UniqueFrame<Link<M>>)
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut CursorOwner<M>>,
Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>,requiresold(self).wf_region(*old(owner), *old(regions)),old(owner).wf_with_region(*old(regions)),old(regions).inv(),frame.inv(),old(frame_own).inv(),frame.wf_with_region(*old(frame_own), *old(regions)),frame.frame_link_inv(*old(frame_own), *old(regions)),ensuresfinal(owner).wf_with_region(*final(regions)),final(self).wf_region(*final(owner), *final(regions)),final(regions).inv(),final(owner).list_own.list
== old(owner).list_own.list.insert(old(owner).index, final(frame_own).meta_own),old(owner).list_own.list_id != 0
==> final(owner).list_own.list_id == old(owner).list_own.list_id,final(owner).list_own.list_id != 0,final(owner).index == old(owner).index + 1,final(frame_own).meta_own.paddr == old(frame_own).meta_own.paddr,final(frame_own).meta_own.in_list == final(owner).list_own.list_id,final(owner)@ == old(owner)@.insert(final(frame_own).meta_own@),Inserts a frame before the current frame.
If the cursor is pointing at the “ghost” non-element then the new
element is inserted at the back of the LinkedList.
§Verified Properties
§Preconditions
The cursor must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects.
- The new frame must be active, so that it is valid to call
into_rawon it.
§Postconditions
- The new frame is inserted into the list, immediately before the current index.
- The list invariants are preserved.
§Safety
- This function calls
into_rawon the frame, so the caller must ensure that the frame is active and has not been forgotten already to avoid a memory leak. If the caller attempts to insert a forgotten frame, the invariant aroundinto_rawandfrom_rawwill be violated. But, it is the safe failure case in that it will not cause a double-free. (Note: we should be able to move this requirement into theUniqueFrameinvariants.)
Sourcepub exec fn as_list(&self) -> &LinkedList<M>
pub exec fn as_list(&self) -> &LinkedList<M>
Provides a reference to the linked list.
Source§impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorMut<'a, M>
impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> CursorMut<'a, M>
Sourcepub open spec fn wf_region(self, owner: CursorOwner<M>, regions: MetaRegionOwners) -> bool
pub open spec fn wf_region(self, owner: CursorOwner<M>, regions: MetaRegionOwners) -> bool
{
&&& 0 <= owner.index < owner.length()
==> self.current.is_some()
&& self.current->0.addr() == owner.list_own.list[owner.index].paddr
&& owner.list_own.meta_pptr_at(regions, owner.index).addr()
== self.current->0.addr()
&&& owner.index == owner.list_own.list.len() ==> self.current.is_none()
&&& (*self.list).wf_region(owner.list_own, regions)
}Region-based analog of CursorMut::wf: the current-link pointer facts
are stated over the corresponding region-owned slot pointer.
Trait Implementations§
Source§impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> OwnerOf for CursorMut<'a, M>
impl<'a, M: AnyFrameMeta + Repr<MetaSlotSmall>> OwnerOf for CursorMut<'a, M>
Source§open spec fn wf(self, owner: Self::Owner) -> bool
open spec fn wf(self, owner: Self::Owner) -> bool
{
&&& 0 <= owner.index < owner.length()
==> self.current.is_some()
&& self.current->0.addr() == owner.list_own.list[owner.index].paddr
&&& owner.index == owner.list_own.list.len() ==> self.current.is_none()
&&& (*self.list).wf(owner.list_own)
}Structural well-formedness: current matches the link at index’s
address. Pointer-permission facts (pptr/ptr equality) are stated in
wf_region over the region-owned slot pointers.
Source§type Owner = CursorOwner<M>
type Owner = CursorOwner<M>
Inv, indicating that it must
has a consistent state.Auto Trait Implementations§
impl<'a, M> !RefUnwindSafe for CursorMut<'a, M>
impl<'a, M> !UnwindSafe for CursorMut<'a, M>
impl<'a, M> Freeze for CursorMut<'a, M>
impl<'a, M> Send for CursorMut<'a, M>
impl<'a, M> Sync for CursorMut<'a, M>
impl<'a, M> Unpin for CursorMut<'a, M>where
M: Unpin,
impl<'a, M> UnsafeUnpin for CursorMut<'a, M>
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
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: From<T>,
fn obeys_from_spec() -> bool
fn from_spec(v: T) -> VERUS_SPEC__A
§impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__Awhere
VERUS_SPEC__A: Into<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> T
§impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
impl<T, U> IntoSpecImpl<U> for Twhere
U: From<T>,
fn obeys_into_spec() -> bool
fn into_spec(self) -> U
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<A> SpecEq<&A> for Awhere
A: ?Sized,
impl<A> SpecEq<&mut A> for Awhere
A: ?Sized,
impl<A> SpecEq<A> for Awhere
A: ?Sized,
impl<A> SpecEq<Ghost<A>> for A
impl<A> SpecEq<Tracked<A>> for A
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.