Skip to main content

LinkedList

Struct LinkedList 

Source
pub struct LinkedList<M: AnyFrameMeta + Repr<MetaSlotSmall>> {
    pub front: Option<ReprPtr<MetaSlotStorage, Link<M>>>,
    pub back: Option<ReprPtr<MetaSlotStorage, Link<M>>>,
    pub size: usize,
    pub list_id: u64,
}
Expand description

A linked list of frames.

Two key features that LinkedList is different from alloc::collections::LinkedList is that:

  1. It is intrusive, meaning that the links are part of the frame metadata. This allows the linked list to be used without heap allocation. But it disallows a frame to be in multiple linked lists at the same time.
  2. The linked list exclusively own the frames, meaning that it takes unique pointers UniqueFrame. And other bodies cannot from_in_use a frame that is inside a linked list.
  3. We also allow creating cursors at a specific frame, allowing $O(1)$ removal without iterating through the list at a cost of some checks.

§Example

To create metadata types that allows linked list links, wrap the metadata type in Link:

use ostd::{
    mm::{frame::{linked_list::{Link, LinkedList}, Frame}, FrameAllocOptions},
    impl_untyped_frame_meta_for,
};

#[derive(Debug)]
struct MyMeta { mark: usize }

type MyFrame = Frame<Link<MyMeta>>;

impl_untyped_frame_meta_for!(MyMeta);

let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options.alloc_frame_with(Link::new(MyMeta { mark: 1 })).unwrap();
let frame2 = alloc_options.alloc_frame_with(Link::new(MyMeta { mark: 2 })).unwrap();

let mut list = LinkedList::new();
list.push_front(frame1.try_into().unwrap());
list.push_front(frame2.try_into().unwrap());

let mut cursor = list.cursor_front_mut();
assert_eq!(cursor.current_meta().unwrap().mark, 2);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().mark, 1);

§Verified Properties

§Verification Design

The linked list is abstractly represented by a LinkedListOwner:

tracked struct LinkedListOwner<M: AnyFrameMeta + Repr<MetaSlotStorage>> {
    pub list: Seq<LinkOwner>,
    pub list_id: u64,
}

The raw slot and storage permissions for each link are parked in the global MetaRegionOwners, while LinkedListOwner owns the corresponding type-specific Link<M>::ReprPerm. Cursor accessors borrow these independent components together when projecting a Link<M>.

§Invariant

The linked list uniquely owns the raw frames that it contains, so they cannot be used by other data structures. The frame metadata field in_list is equal to list_id for all links in the list. The per-link well-formedness against the region (pointer/permission wiring, next/prev pointer chain) is captured by LinkedListOwner::relate_region (opaque, with per-position LinkedListOwner::relate_region_at). The cursor exposes this via CursorOwner::wf_with_region and CursorMut::wf_region.

§Safety

A given linked list can only have one cursor at a time, so there are no data races. The prev and next fields of the metadata for each link always points to valid links in the list, so the structure is memory safe (will not read or write invalid memory).

Fields§

§front: Option<ReprPtr<MetaSlotStorage, Link<M>>>§back: Option<ReprPtr<MetaSlotStorage, Link<M>>>§size: usize

The number of frames in the list.

§list_id: u64

A lazily initialized ID, used to check whether a frame is in the list. 0 means uninitialized.

Implementations§

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M>

Source

pub const exec fn new() -> Self

Creates a new linked list.

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M>

Source

pub exec fn size(&self) -> s : usize

with
Tracked(owner): Tracked<LinkedListOwner<M>>,
requires
self.wf(owner),
owner.inv(),
ensures
s == owner@.list.len(),

Gets the number of frames in the linked list.

Source

pub exec fn is_empty(&self) -> b : bool

with
Tracked(owner): Tracked<LinkedListOwner<M>>,
requires
self.wf(owner),
owner.inv(),
ensures
b ==> self.size == 0 && self.front is None && self.back is None,
!b ==> self.size > 0 && self.front is Some && self.back is Some,

Tells if the linked list is empty.

Source

pub exec fn push_front(&mut self, frame: UniqueFrame<Link<M>>)

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>,
requires
old(self).wf_region(*old(owner), *old(regions)),
old(owner).relate_region(*old(regions)),
frame.inv(),
old(frame_own).inv(),
frame.wf_with_region(*old(frame_own), *old(regions)),
frame.frame_link_inv(*old(frame_own), *old(regions)),
old(regions).inv(),
ensures
final(self).wf_region(*final(owner), *final(regions)),
final(owner).inv(),
final(owner).relate_region(*final(regions)),
final(regions).inv(),
final(owner).list == old(owner).list.insert(0, final(frame_own).meta_own),
old(owner).list_id != 0 ==> final(owner).list_id == old(owner).list_id,
final(owner).list_id != 0,
final(frame_own).meta_own.slot_vaddr == old(frame_own).meta_own.slot_vaddr,
final(frame_own).meta_own.in_list == final(owner).list_id,

Pushes a frame to the front of the linked list.

§Verified Properties
§Preconditions

The list 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_raw on it inside of insert_before.

§Postconditions

The new frame is inserted at the front of the list. The list invariants are preserved.

§Safety

See [insert_before] for the safety guarantees.

Source

pub exec fn pop_front(&mut self) -> r : Option<UniqueFrame<Link<M>>>

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
->
frame_owner: Tracked<Option<UniqueFrameOwner<Link<M>>>>,
requires
old(regions).inv(),
old(self).wf_region(*old(owner), *old(regions)),
old(owner).relate_region(*old(regions)),
ensures
final(regions).inv(),
final(owner).inv(),
final(owner).relate_region(*final(regions)),
final(self).wf_region(*final(owner), *final(regions)),
final(owner).list_id == old(owner).list_id,
r is Some == (old(owner).list.len() > 0),
r is Some == frame_owner@ is Some,
r matches Some(
    frame,
) ==> (frame_owner@ matches Some(
    fo,
) ==> {
    &&& final(owner).list == old(owner).list.remove(0)
    &&& fo.meta_own@ == old(owner).list[0]@
    &&& frame.inv()
    &&& fo.inv()
    &&& frame.wf(fo)
    &&& frame.wf_with_region(fo, *final(regions))
    &&& frame.frame_link_inv(fo, *final(regions))

}),
r is None
    ==> *final(owner) == *old(owner) && *final(self) == *old(self)
        && *final(regions) == *old(regions),

Pops a frame from the front of the linked list.

§Verified Properties
§Preconditions

The list must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects.

§Postconditions
  • The list invariants are preserved.
  • Returns the front frame and its owner, or None if the list is empty.
§Safety

See [take_current] for the safety guarantees.

Source

pub exec fn push_back(&mut self, frame: UniqueFrame<Link<M>>)

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
Tracked(frame_own): Tracked<&mut UniqueFrameOwner<Link<M>>>,
requires
old(self).wf_region(*old(owner), *old(regions)),
old(owner).relate_region(*old(regions)),
frame.inv(),
old(frame_own).inv(),
frame.wf_with_region(*old(frame_own), *old(regions)),
frame.frame_link_inv(*old(frame_own), *old(regions)),
old(regions).inv(),
ensures
final(self).wf_region(*final(owner), *final(regions)),
final(owner).inv(),
final(owner).relate_region(*final(regions)),
final(regions).inv(),
final(owner).list
    == old(owner).list.insert(old(owner).list.len() as int, final(frame_own).meta_own),
old(owner).list_id != 0 ==> final(owner).list_id == old(owner).list_id,
final(owner).list_id != 0,
final(frame_own).meta_own.slot_vaddr == old(frame_own).meta_own.slot_vaddr,
final(frame_own).meta_own.in_list == final(owner).list_id,

Pushes a frame to the back of the linked list.

§Verified Properties
§Preconditions

The list 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_raw on it inside of insert_before.

§Postconditions
  • The new frame is inserted at the back of the list.
  • The list invariants are preserved.
§Safety

See [insert_before] for the safety guarantees.

Source

pub exec fn pop_back(&mut self) -> r : Option<UniqueFrame<Link<M>>>

with
Tracked(regions): Tracked<&mut MetaRegionOwners>,
Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
->
frame_owner: Tracked<Option<UniqueFrameOwner<Link<M>>>>,
requires
old(regions).inv(),
old(self).wf_region(*old(owner), *old(regions)),
old(owner).relate_region(*old(regions)),
ensures
final(regions).inv(),
final(owner).inv(),
final(owner).relate_region(*final(regions)),
final(self).wf_region(*final(owner), *final(regions)),
final(owner).list_id == old(owner).list_id,
(r is Some) == (old(owner).list.len() > 0),
(r is Some) == (frame_owner@ is Some),
r matches Some(
    frame,
) ==> (frame_owner@ matches Some(
    fo,
) ==> {
    &&& final(owner).list == old(owner).list.remove(old(owner).list.len() - 1)
    &&& fo.meta_own@ == old(owner).list[old(owner).list.len() - 1]@
    &&& frame.inv()
    &&& fo.inv()
    &&& frame.wf(fo)
    &&& frame.wf_with_region(fo, *final(regions))
    &&& frame.frame_link_inv(fo, *final(regions))

}),
r is None
    ==> *final(owner) == *old(owner) && *final(self) == *old(self)
        && *final(regions) == *old(regions),

Pops a frame from the back of the linked list.

§Verified Properties
§Preconditions
  • The list must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects.
§Postconditions
  • Returns the back frame and its owner, or None if the list is empty.
  • The list invariants are preserved.
§Safety

See [take_current] for the safety guarantees.

Source

pub exec fn contains(&mut self, frame: Paddr) -> r : bool

with
Tracked(regions): Tracked<&MetaRegionOwners>,
Tracked(owner): Tracked<&LinkedListOwner<M>>,
requires
regions.inv(),
old(self).wf(*owner),
owner.relate_region(*regions),
ensures
(valid_frame_paddr(frame)
    && exists |i: int| {
        0 <= i < owner.list.len()
            && #[trigger] meta_to_index(owner.list[i].slot_vaddr)
                == frame_to_index(frame)
    }) ==> r,
returns
valid_frame_paddr(frame)
    && regions.slot_owners[frame_to_index(frame)].in_list_perm.value()
        == final(self).list_id,

Tells if a frame is in the list.

§Verified Properties
§Preconditions
  • The list must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects.
  • The list owner must relate its links to the region permissions.
§Postconditions
  • The result is true exactly when the frame address is valid and its region-owned in_list tag equals the list’s ID after lazy initialization.
  • A valid frame in the owner’s list always returns true.
§Safety
  • lazy_get_id uses atomic memory accesses, so there are no data races.
  • We assume that the ID allocator has an available ID if the list previously didn’t have one, but the consequence if that is not the case is a failsafe panic.
  • Everything else conforms to the safe interface.
Source

pub exec fn cursor_mut_at(&mut self, frame: Paddr) -> r : Option<CursorMut<'_, M>>

with
Tracked(regions): Tracked<&MetaRegionOwners>,
Tracked(owner): Tracked<&mut LinkedListOwner<M>>,
->
cursor_owner: Tracked<Option<CursorOwner<M>>>,
requires
regions.inv(),
old(self).wf_region(*old(owner), *regions),
old(owner).relate_region(*regions),
list_registry_ok(*regions, *old(owner)),
old(owner).list_id != 0,
ensures
!valid_frame_paddr(frame) ==> r is None,
r is Some == cursor_owner@ is Some,
(r is Some)
    == (valid_frame_paddr(frame)
        && exists |i: int| {
            0 <= i < old(owner).list.len()
                && #[trigger] meta_to_index(old(owner).list[i].slot_vaddr)
                    == frame_to_index(frame)
        }),
r is None
    ==> {
        &&& *final(owner) == *old(owner)
        &&& *final(self) == *old(self)
        &&& final(self).wf_region(*final(owner), *regions)
        &&& final(owner).inv()

    },
r matches Some(
    cursor,
) ==> (cursor_owner@ matches Some(
    co,
) ==> {
    &&& co.list_own == *old(owner)
    &&& 0 <= co.index < co.list_own.list.len()
    &&& meta_to_index(co.list_own.list[co.index].slot_vaddr) == frame_to_index(frame)
    &&& cursor.wf_region(co, *regions)
    &&& co.wf_with_region(*regions)
    &&& cursor.wf(co)
    &&& co.inv()
    &&& *cursor.list == *old(self)
    &&& *final(self) == *final(cursor.list)

}),

Gets a cursor at the specified frame if the frame is in the list.

This method fails if the frame is not in the list.

§Verified Properties
§Preconditions
  • The list must be well-formed, with the pointers to its links’ metadata slots matching the tracked permission objects.
  • The list owner must match the list and region permissions, and its membership registry must be consistent with the region’s in_list tags.
  • The list must already have a non-zero ID: lazy_get_id does not yet model freshness against the region’s in_list tags for a fresh list.
§Postconditions
  • A cursor is returned exactly when the valid frame belongs to the list. Its owner has an in-range index matching the frame, and the cursor is well-formed with the region permissions.
  • The returned cursor and its tracked owner are either both present or both absent.
§Safety
  • lazy_get_id uses atomic memory accesses, so there are no data races.
Source

pub exec fn cursor_front_mut(&mut self) -> r : CursorMut<'_, M>

ensures
r.current == old(self).front,
*r.list == *old(self),
*final(self) == *final(r.list),

Gets a cursor at the front that can mutate the linked list links.

If the list is empty, the cursor points to the “ghost” non-element.

§Verified Properties
§Safety

This function is written in safe Rust and there is no undefined behavior.

Source

pub exec fn cursor_back_mut(&mut self) -> r : CursorMut<'_, M>

ensures
r.current == old(self).back,
*r.list == *old(self),
*final(self) == *final(r.list),

Gets a cursor at the back that can mutate the linked list links.

If the list is empty, the cursor points to the “ghost” non-element.

§Verified Properties
§Safety

This function is written in safe Rust and there is no undefined behavior.

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M>

Source

pub exec fn drop( self, Tracked(owner): Tracked<&mut LinkedListOwner<M>>, Tracked(regions): Tracked<&mut MetaRegionOwners>, )

requires
self.wf(*old(owner)),
old(owner).inv(),
old(regions).inv(),
forall |i: int| {
    0 <= i < old(owner).list.len()
        ==> {
            let idx = meta_to_index(old(owner).list[i].slot_vaddr);
            &&& old(regions).contains(idx)
            &&& old(regions).ref_count(idx) == REF_COUNT_UNIQUE
            &&& old(regions).slot_owners[idx].paths_in_pt.is_empty()

        }
},
forall |i: int, j: int| {
    0 <= i < j < old(owner).list.len()
        ==> meta_to_index(old(owner).list[i].slot_vaddr)
            != meta_to_index(old(owner).list[j].slot_vaddr)
},
old(owner).relate_region(*old(regions)),
ensures
final(owner).list.len() == 0,
forall |idx: int| {
    (forall |i: int| {
        0 <= i < old(owner).list.len()
            ==> idx != meta_to_index(old(owner).list[i].slot_vaddr)
    })
        ==> {
            &&& final(regions).slot_owners[idx].usage
                == old(regions).slot_owners[idx].usage
            &&& final(regions).slot_owners[idx].slot_vaddr
                == old(regions).slot_owners[idx].slot_vaddr
            &&& final(regions).slot_owners[idx].paths_in_pt
                == old(regions).slot_owners[idx].paths_in_pt

        }
},
final(regions).slots.dom() =~= old(regions).slots.dom(),
final(regions).inv(),

Releases every frame owned by the list.

§Verified Properties

Requires matching list ownership and region permissions, with every list frame uniquely owned and absent from page tables. Empties the list owner, preserves the region invariant, and leaves unrelated frames’ usage, metadata addresses, and page-table ownership unchanged.

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> LinkedList<M>

Source

pub open spec fn wf_region( self, owner: LinkedListOwner<M>, regions: MetaRegionOwners, ) -> bool

{
    &&& self.front is None <==> owner.list.len() == 0
    &&& self.back is None <==> owner.list.len() == 0
    &&& owner.list.len() > 0
        ==> self.front is Some && self.front->0.addr() == owner.list[0].slot_vaddr
            && owner.meta_pptr_at(regions, 0).addr() == self.front->0.addr()
            && self.back is Some
            && self.back->0.addr() == owner.list[owner.list.len() - 1].slot_vaddr
            && owner.meta_pptr_at(regions, owner.list.len() - 1).addr()
                == self.back->0.addr()
    &&& self.size == owner.list.len()
    &&& self.list_id == owner.list_id

}

Region-based analog of LinkedList::wf: the front/back pointer facts are stated directly over the region-owned slot pointers.

Trait Implementations§

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> Default for LinkedList<M>

Source§

exec fn default() -> Self

Source§

impl<M: AnyFrameMeta + Repr<MetaSlotSmall>> OwnerOf for LinkedList<M>

Source§

open spec fn wf(self, owner: Self::Owner) -> bool

{
    &&& self.front is None <==> owner.list.len() == 0
    &&& self.back is None <==> owner.list.len() == 0
    &&& owner.list.len() > 0
        ==> self.front is Some && self.front->0.addr() == owner.list[0].slot_vaddr
            && self.back is Some
            && self.back->0.addr() == owner.list[owner.list.len() - 1].slot_vaddr
    &&& self.size == owner.list.len()
    &&& self.list_id == owner.list_id

}

Structural well-formedness of the LinkedList against its owner: size, list_id, and front/back addresses match. The per-link pointer-permission facts (pptr/ptr equality against the front/back) live in wf_region, which sources them from MetaRegionOwners.

Source§

type Owner = LinkedListOwner<M>

The owner of the concrete type. The Owner must implement Inv, indicating that it must has a consistent state.

Auto Trait Implementations§

§

impl<M> !RefUnwindSafe for LinkedList<M>

§

impl<M> Freeze for LinkedList<M>

§

impl<M> Send for LinkedList<M>

§

impl<M> Sync for LinkedList<M>

§

impl<M> Unpin for LinkedList<M>
where M: Unpin,

§

impl<M> UnsafeUnpin for LinkedList<M>

§

impl<M> UnwindSafe for LinkedList<M>
where M: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, VERUS_SPEC__A> FromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: From<T>,

§

fn obeys_from_spec() -> bool

§

fn from_spec(v: T) -> VERUS_SPEC__A

§

impl<T> FromSpecImpl<T> for T

§

fn obeys_from_spec() -> bool

§

fn from_spec(v: T) -> T

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T, VERUS_SPEC__A> IntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: Into<T>,

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> T

§

impl<T, U> IntoSpecImpl<U> for T
where U: From<T>,

§

fn obeys_into_spec() -> bool

§

fn into_spec(self) -> U

§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows 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) -> R
where R: 'a,

Mutably borrows 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
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows 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
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows 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
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<A> SpecEq<&A> for A
where A: ?Sized,

§

impl<A> SpecEq<&mut A> for A
where A: ?Sized,

§

impl<A> SpecEq<A> for A
where A: ?Sized,

§

impl<A> SpecEq<Ghost<A>> for A

§

impl<A> SpecEq<Tracked<A>> for A

§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .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
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .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
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, VERUS_SPEC__A> TryFromSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryFrom<T>,

§

fn obeys_try_from_spec() -> bool

§

fn try_from_spec( v: T, ) -> Result<VERUS_SPEC__A, <VERUS_SPEC__A as TryFrom<T>>::Error>

Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T, VERUS_SPEC__A> TryIntoSpec<T> for VERUS_SPEC__A
where VERUS_SPEC__A: TryInto<T>,

§

fn obeys_try_into_spec() -> bool

§

fn try_into_spec(self) -> Result<T, <VERUS_SPEC__A as TryInto<T>>::Error>

§

impl<T, U> TryIntoSpecImpl<U> for T
where U: TryFrom<T>,

§

fn obeys_try_into_spec() -> bool

§

fn try_into_spec(self) -> Result<U, <U as TryFrom<T>>::Error>