use super::super::prelude::*; use core::marker::PointeeSized; use verus as verus_skip_verusfmt; verus_skip_verusfmt! { #[verifier::external_trait_specification] pub trait ExTuple { type ExternalTraitSpecificationFor: core::marker::Tuple; } #[verifier::external_trait_specification] pub trait ExFnOnce { type ExternalTraitSpecificationFor: core::ops::FnOnce; type Output; } #[verifier::external_trait_specification] pub trait ExFnMut: FnOnce { type ExternalTraitSpecificationFor: core::ops::FnMut; } #[verifier::external_trait_specification] pub trait ExFn: FnMut { type ExternalTraitSpecificationFor: core::ops::Fn; } #[verifier::external_trait_specification] pub trait ExDeref: PointeeSized { type ExternalTraitSpecificationFor: core::ops::Deref; type Target: ?Sized; fn deref(&self) -> &Self::Target; } #[verifier::external_trait_specification] pub trait ExDerefMut: core::ops::Deref + PointeeSized { type ExternalTraitSpecificationFor: core::ops::DerefMut; fn deref_mut(&mut self) -> &mut Self::Target; } #[verifier::external_trait_specification] #[verifier::external_trait_extension(IndexSpec via IndexSpecImpl)] pub trait ExIndex where Idx: ?Sized { type ExternalTraitSpecificationFor: core::ops::Index; type Output: ?Sized; // NOTE: this used as a precondition for both `Index` and `IndexMut`, // since both share the same `s[i]` syntax. spec fn index_req(&self, index: &Idx) -> bool; fn index(&self, index: Idx) -> (output: &Self::Output) where Idx: Sized requires self.index_req(&index), ; } #[verifier::external_trait_specification] pub trait ExIndexMut: core::ops::Index where Idx: ?Sized { type ExternalTraitSpecificationFor: core::ops::IndexMut; fn index_mut(&mut self, index: Idx) -> (output: &mut Self::Output) where Idx: Sized requires self.index_req(&index), ; } #[verifier::external_trait_specification] pub trait ExInteger: Copy { type ExternalTraitSpecificationFor: Integer; } #[verifier::external_trait_specification] pub trait ExSpecOrd { type ExternalTraitSpecificationFor: SpecOrd; } #[cfg(not(verus_verify_core))] #[verifier::external_trait_specification] pub trait ExAllocator { type ExternalTraitSpecificationFor: core::alloc::Allocator; } #[verifier::external_trait_specification] pub trait ExFreeze: PointeeSized { type ExternalTraitSpecificationFor: core::marker::Freeze; } #[verifier::external_trait_specification] pub trait ExHash: PointeeSized { type ExternalTraitSpecificationFor: core::hash::Hash; } #[verifier::external_trait_specification] pub trait ExPtrPointee: PointeeSized { type ExternalTraitSpecificationFor: core::ptr::Pointee; type Metadata: Copy + Send + Sync + Ord + core::hash::Hash + Unpin + core::fmt::Debug + Sized + core::marker::Freeze; } #[verifier::external_trait_specification] pub trait ExBorrow where Borrowed: ?Sized { type ExternalTraitSpecificationFor: core::borrow::Borrow; } #[verifier::external_trait_specification] pub trait ExStructural { type ExternalTraitSpecificationFor: Structural; } // Since this trait involves the unstable library feature `const_destruct`, // we only enable it when verifying core #[cfg(verus_verify_core)] #[verifier::external_trait_specification] trait ExDestruct: PointeeSized { type ExternalTraitSpecificationFor: core::marker::Destruct; } #[verifier::external_trait_specification] pub trait ExMetaSized { type ExternalTraitSpecificationFor: core::marker::MetaSized; } pub assume_specification[ core::mem::swap:: ](a: &mut T, b: &mut T) ensures *final(a) == *old(b), *final(b) == *old(a), opens_invariants none no_unwind ; #[verifier::external_type_specification] pub struct ExOrdering(core::cmp::Ordering); #[verifier::external_type_specification] #[verifier::accept_recursive_types(V)] #[verifier::ext_equal] pub struct ExOption(core::option::Option); #[verifier::external_type_specification] #[verifier::accept_recursive_types(T)] #[verifier::reject_recursive_types_in_ground_variants(E)] pub struct ExResult(core::result::Result); // I don't really expect this to be particularly useful; // this is mostly here because I wanted an easy way to test // the combination of external_type_specification & external_body // in a cross-crate context. #[verifier::external_type_specification] #[verifier::external_body] pub struct ExDuration(core::time::Duration); #[verifier::external_type_specification] #[verifier::accept_recursive_types(V)] pub struct ExPhantomData(core::marker::PhantomData); pub assume_specification[ core::intrinsics::likely ](b: bool) -> (c: bool) ensures c == b, ; pub assume_specification[ core::intrinsics::unlikely ](b: bool) -> (c: bool) ensures c == b, ; pub assume_specification T>[ bool::then ](b: bool, f: F) -> (ret: Option) requires b ==> f.requires(()), ensures if b { ret.is_some() && f.ensures((), ret.unwrap()) } else { ret.is_none() }, ; pub assume_specification [core::hint::must_use] (value: T) -> (ret: T) ensures ret == value, ; pub assume_specification [core::panicking::panic] (s: &'static str) -> ! requires false, ; pub assume_specification [core::panicking::panic_fmt] (s: core::fmt::Arguments<'_>) -> ! requires false, ; // Called by `assert_eq!` and `assert_ne!`; not external_body, since the macros construct an `AssertKind` #[verifier::external_type_specification] pub struct ExAssertKind(core::panicking::AssertKind); pub assume_specification[ core::panicking::assert_failed:: ]( kind: core::panicking::AssertKind, left: &T, right: &U, args: Option>, ) -> ! where T: core::fmt::Debug + ?Sized, U: core::fmt::Debug + ?Sized, requires false, ; } // verus! #[verifier::external_type_specification] #[verifier::external_body] #[verifier::accept_recursive_types(T)] pub struct ExAssertParamIsClone(core::clone::AssertParamIsClone);