Skip to main content

vstd/std_specs/
core.rs

1use super::super::prelude::*;
2use core::marker::PointeeSized;
3
4use verus as verus_skip_verusfmt;
5verus_skip_verusfmt! {
6
7#[verifier::external_trait_specification]
8pub trait ExTuple {
9    type ExternalTraitSpecificationFor: core::marker::Tuple;
10}
11
12#[verifier::external_trait_specification]
13pub trait ExFnOnce<Args: core::marker::Tuple> {
14    type ExternalTraitSpecificationFor: core::ops::FnOnce<Args>;
15
16    type Output;
17}
18
19#[verifier::external_trait_specification]
20pub trait ExFnMut<Args: core::marker::Tuple>: FnOnce<Args> {
21    type ExternalTraitSpecificationFor: core::ops::FnMut<Args>;
22}
23
24#[verifier::external_trait_specification]
25pub trait ExFn<Args: core::marker::Tuple>: FnMut<Args> {
26    type ExternalTraitSpecificationFor: core::ops::Fn<Args>;
27}
28
29#[verifier::external_trait_specification]
30pub trait ExDeref: PointeeSized {
31    type ExternalTraitSpecificationFor: core::ops::Deref;
32
33    type Target: ?Sized;
34
35    fn deref(&self) -> &Self::Target;
36}
37
38#[verifier::external_trait_specification]
39pub trait ExDerefMut: core::ops::Deref + PointeeSized {
40    type ExternalTraitSpecificationFor: core::ops::DerefMut;
41
42    fn deref_mut(&mut self) -> &mut Self::Target;
43}
44
45#[verifier::external_trait_specification]
46#[verifier::external_trait_extension(IndexSpec via IndexSpecImpl)]
47pub trait ExIndex<Idx> where Idx: ?Sized {
48    type ExternalTraitSpecificationFor: core::ops::Index<Idx>;
49
50    type Output: ?Sized;
51
52    // NOTE: this used as a precondition for both `Index` and `IndexMut`,
53    // since both share the same `s[i]` syntax.
54    spec fn index_req(&self, index: &Idx) -> bool;
55
56    fn index(&self, index: Idx) -> (output: &Self::Output) where Idx: Sized
57        requires
58            self.index_req(&index),
59    ;
60}
61
62#[verifier::external_trait_specification]
63pub trait ExIndexMut<Idx>: core::ops::Index<Idx> where Idx: ?Sized {
64    type ExternalTraitSpecificationFor: core::ops::IndexMut<Idx>;
65
66    fn index_mut(&mut self, index: Idx) -> (output: &mut Self::Output) where Idx: Sized
67        requires
68            self.index_req(&index),
69    ;
70}
71
72#[verifier::external_trait_specification]
73pub trait ExInteger: Copy {
74    type ExternalTraitSpecificationFor: Integer;
75}
76
77#[verifier::external_trait_specification]
78pub trait ExSpecOrd<Rhs> {
79    type ExternalTraitSpecificationFor: SpecOrd<Rhs>;
80}
81
82#[cfg(not(verus_verify_core))]
83#[verifier::external_trait_specification]
84pub trait ExAllocator {
85    type ExternalTraitSpecificationFor: core::alloc::Allocator;
86}
87
88#[verifier::external_trait_specification]
89pub trait ExFreeze: PointeeSized {
90    type ExternalTraitSpecificationFor: core::marker::Freeze;
91}
92
93// Declaring the methods means an impl of `Hasher` cannot add a `requires` clause, which
94// std's callers (such as the `Hash` impls) would not satisfy. The unstable `write_str` and
95// `write_length_prefix` are not declared.
96#[verifier::external_trait_specification]
97pub trait ExHasher {
98    type ExternalTraitSpecificationFor: core::hash::Hasher;
99
100    fn finish(&self) -> u64;
101
102    fn write(&mut self, bytes: &[u8]);
103
104    fn write_u8(&mut self, i: u8);
105
106    fn write_u16(&mut self, i: u16);
107
108    fn write_u32(&mut self, i: u32);
109
110    fn write_u64(&mut self, i: u64);
111
112    fn write_u128(&mut self, i: u128);
113
114    fn write_usize(&mut self, i: usize);
115
116    fn write_i8(&mut self, i: i8);
117
118    fn write_i16(&mut self, i: i16);
119
120    fn write_i32(&mut self, i: i32);
121
122    fn write_i64(&mut self, i: i64);
123
124    fn write_i128(&mut self, i: i128);
125
126    fn write_isize(&mut self, i: isize);
127}
128
129// Declaring the methods means an impl of `Hash` cannot add a `requires` clause, which
130// std's callers (such as `HashMap::insert`) would not satisfy.
131#[verifier::external_trait_specification]
132pub trait ExHash: PointeeSized {
133    type ExternalTraitSpecificationFor: core::hash::Hash;
134
135    fn hash<H: core::hash::Hasher>(&self, state: &mut H);
136
137    fn hash_slice<H: core::hash::Hasher>(data: &[Self], state: &mut H) where Self: Sized;
138}
139
140#[verifier::external_trait_specification]
141pub trait ExPtrPointee: PointeeSized {
142    type ExternalTraitSpecificationFor: core::ptr::Pointee;
143
144    type Metadata:
145        Copy + Send + Sync + Ord + core::hash::Hash + Unpin + core::fmt::Debug + Sized + core::marker::Freeze;
146}
147
148#[verifier::external_trait_specification]
149pub trait ExBorrow<Borrowed> where Borrowed: ?Sized {
150    type ExternalTraitSpecificationFor: core::borrow::Borrow<Borrowed>;
151}
152
153#[verifier::external_trait_specification]
154pub trait ExStructural {
155    type ExternalTraitSpecificationFor: Structural;
156}
157
158// Since this trait involves the unstable library feature `const_destruct`,
159// we only enable it when verifying core
160#[cfg(verus_verify_core)]
161#[verifier::external_trait_specification]
162trait ExDestruct: PointeeSized {
163    type ExternalTraitSpecificationFor: core::marker::Destruct;
164}
165
166#[verifier::external_trait_specification]
167pub trait ExMetaSized {
168    type ExternalTraitSpecificationFor: core::marker::MetaSized;
169}
170
171pub assume_specification<T>[ core::mem::swap::<T> ](a: &mut T, b: &mut T)
172    ensures
173        *final(a) == *old(b),
174        *final(b) == *old(a),
175    opens_invariants none
176    no_unwind
177;
178
179#[verifier::external_type_specification]
180pub struct ExOrdering(core::cmp::Ordering);
181
182#[verifier::external_type_specification]
183#[verifier::accept_recursive_types(V)]
184#[verifier::ext_equal]
185pub struct ExOption<V>(core::option::Option<V>);
186
187#[verifier::external_type_specification]
188#[verifier::accept_recursive_types(T)]
189#[verifier::reject_recursive_types_in_ground_variants(E)]
190pub struct ExResult<T, E>(core::result::Result<T, E>);
191
192// I don't really expect this to be particularly useful;
193// this is mostly here because I wanted an easy way to test
194// the combination of external_type_specification & external_body
195// in a cross-crate context.
196#[verifier::external_type_specification]
197#[verifier::external_body]
198pub struct ExDuration(core::time::Duration);
199
200#[verifier::external_type_specification]
201#[verifier::accept_recursive_types(V)]
202pub struct ExPhantomData<V: PointeeSized>(core::marker::PhantomData<V>);
203
204pub assume_specification[ core::intrinsics::likely ](b: bool) -> (c: bool)
205    ensures
206        c == b,
207;
208
209pub assume_specification[ core::intrinsics::unlikely ](b: bool) -> (c: bool)
210    ensures
211        c == b,
212;
213
214pub assume_specification<T, F: FnOnce() -> T>[ bool::then ](b: bool, f: F) -> (ret: Option<T>)
215    requires
216        b ==> f.requires(()),
217    ensures
218        if b {
219            ret.is_some() && f.ensures((), ret.unwrap())
220        } else {
221            ret.is_none()
222        },
223;
224
225pub assume_specification<T> [core::hint::must_use] (value: T) -> (ret: T)
226    ensures
227        ret == value,
228;
229
230pub assume_specification [core::panicking::panic] (s: &'static str) -> !
231    requires
232        false,
233;
234
235pub assume_specification [core::panicking::panic_fmt] (s: core::fmt::Arguments<'_>) -> !
236    requires
237        false,
238;
239
240// Called by `assert_eq!` and `assert_ne!`; not external_body, since the macros construct an `AssertKind`
241#[verifier::external_type_specification]
242pub struct ExAssertKind(core::panicking::AssertKind);
243
244pub assume_specification<T, U>[ core::panicking::assert_failed::<T, U> ](
245    kind: core::panicking::AssertKind,
246    left: &T,
247    right: &U,
248    args: Option<core::fmt::Arguments<'_>>,
249) -> !
250    where
251        T: core::fmt::Debug + ?Sized,
252        U: core::fmt::Debug + ?Sized,
253    requires
254        false,
255;
256
257} // verus!
258
259#[verifier::external_type_specification]
260#[verifier::external_body]
261#[verifier::accept_recursive_types(T)]
262pub struct ExAssertParamIsClone<T: Clone + PointeeSized>(core::clone::AssertParamIsClone<T>);