creusot_std/std/
convert.rs1use crate::prelude::*;
2#[cfg(creusot)]
3use core::marker::PointeeSized;
4#[cfg(all(creusot, feature = "std"))]
5use std::alloc::Allocator;
6
7extern_spec! {
8 mod core {
9 mod convert {
10 trait AsRef<T: PointeeSized>: PointeeSized {
11 fn as_ref(&self) -> &T;
12 }
13
14 trait AsMut<T: PointeeSized>: PointeeSized {
15 fn as_mut(&mut self) -> &mut T;
16 }
17
18 trait From<T> {
19 fn from(value: T) -> Self;
20 }
21 }
22 }
23
24 impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T
25 where
26 T: AsRef<U>,
27 {
28 #[requires(<T as AsRef<U>>::as_ref.precondition((*self,)))]
29 #[ensures(<T as AsRef<U>>::as_ref.postcondition((*self,), result))]
30 fn as_ref<'b>(&'b self) -> &'b U {
31 <T as AsRef<U>>::as_ref(*self)
32 }
33 }
34
35 impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T
36 where
37 T: AsRef<U>,
38 {
39 #[requires(<T as AsRef<U>>::as_ref.precondition((*self,)))]
40 #[ensures(<T as AsRef<U>>::as_ref.postcondition((*self,), result))]
41 fn as_ref<'b>(&'b self) -> &'b U {
42 <T as AsRef<U>>::as_ref(*self)
43 }
44 }
45
46 impl<T> AsRef<[T]> for [T] {
47 #[check(ghost)]
48 #[ensures(result == self)]
49 fn as_ref(&self) -> &[T] {
50 self
51 }
52 }
53
54 impl AsRef<str> for str {
55 #[check(ghost)]
56 #[ensures(result == self)]
57 fn as_ref(&self) -> &str {
58 self
59 }
60 }
61
62 impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T
63 where
64 T: AsMut<U>,
65 {
66 #[requires(<T as AsMut<U>>::as_mut.precondition((*self,)))]
67 #[ensures(^*self == ^^self)]
68 #[ensures(exists<s: &mut T> *s == **self && ^s == *^self &&
69 <T as AsMut<U>>::as_mut.postcondition((s,), result)
70 )]
71 fn as_mut<'b>(&'b mut self) -> &'b mut U {
72 (*self).as_mut()
73 }
74 }
75
76 impl<T> AsMut<[T]> for [T] {
77 #[check(ghost)]
78 #[ensures(result == self)]
79 fn as_mut(&mut self) -> &mut [T] {
80 self
81 }
82 }
83
84 impl AsMut<str> for str {
85 #[check(ghost)]
86 #[ensures(result == self)]
87 fn as_mut(&mut self) -> &mut str {
88 self
89 }
90 }
91
92 impl<T> From<T> for T {
93 #[check(ghost)]
94 #[ensures(result == self)]
95 fn from(self) -> T;
96 }
97
98 impl<T, U: From<T>> Into<U> for T {
99 #[requires(<U as From<T>>::from.precondition((self,)))]
101 #[ensures(<U as From<T>>::from.postcondition((self,), result))]
102 fn into(self) -> U {
103 U::from(self)
104 }
105 }
106
107 impl<T> From<T> for Option<T> {
108 #[check(ghost)]
109 #[ensures(result == Some(x))]
110 fn from(x: T) -> Self;
111 }
112
113 impl<T, U: TryFrom<T>> TryInto<U> for T {
114 #[requires(U::try_from.precondition((self,)))]
115 #[ensures(U::try_from.postcondition((self,), result))]
116 fn try_into(self) -> Result<U, U::Error> {
117 U::try_from(self)
118 }
119 }
120}
121
122#[cfg(feature = "std")]
123extern_spec! {
124 impl<T> From<T> for Box<T> {
125 #[check(ghost)]
126 #[ensures(*result == x)]
127 fn from(x: T) -> Self;
128 }
129
130 impl<T: Clone> From<&[T]> for Box<[T]>
131 {
132 #[ensures(result@.len() == s@.len())]
134 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
135 fn from(s: &[T]) -> Self;
136 }
138
139 impl<T: Clone> From<&mut [T]> for Box<[T]>
140 {
141 #[ensures(result@.len() == s@.len())]
143 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
144 #[ensures(^s == *s)]
145 fn from(s: &mut [T]) -> Self {
146 Box::<[T]>::from(&*s)
147 }
148 }
149
150 impl<T, const N: usize> From<[T; N]> for Box<[T]> {
151 #[check(ghost)]
152 #[ensures(result@ == s@)]
153 fn from(s: [T; N]) -> Self {
154 Box::new(s)
155 }
156 }
157
158 impl<T: Clone> From<&[T]> for Vec<T>
159 {
160 #[ensures(result@.len() == s@.len())]
162 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
163 fn from(s: &[T]) -> Self {
164 s.to_vec()
165 }
166 }
167
168 impl<T: Clone> From<&mut [T]> for Vec<T>
169 {
170 #[ensures(result@.len() == s@.len())]
172 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
173 #[ensures(^s == *s)]
174 fn from(s: &mut [T]) -> Self {
175 s.to_vec()
176 }
177 }
178
179 impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
180 #[check(ghost)]
181 #[ensures(result@ == s@)]
182 fn from(s: Box<[T], A>) -> Self {
183 s.into_vec()
184 }
185 }
186
187 impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
188 #[ensures(result@.len() == N@)]
190 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
191 fn from(s: &[T; N]) -> Self {
192 Vec::<T>::from(s.as_slice())
193 }
194 }
195
196 impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
197 #[ensures(result@.len() == N@)]
199 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
200 #[ensures(^s == *s)]
201 fn from(s: &mut [T; N]) -> Self {
202 Vec::<T>::from(s.as_mut_slice())
203 }
204 }
205
206 impl<T, const N: usize> From<[T; N]> for Vec<T> {
207 #[check(ghost)]
208 #[ensures(result@ == s@)]
209 fn from(s: [T; N]) -> Self {
210 <[T]>::into_vec(Box::new(s))
211 }
212 }
213
214 impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
215 #[check(ghost)]
216 #[ensures(result@ == v@)]
217 fn from(v: Vec<T, A>) -> Self {
218 v.into_boxed_slice()
219 }
220 }
221
222 impl From<&String> for String {
223 #[check(ghost)]
224 #[ensures(result@ == s@)]
225 fn from(s: &String) -> Self;
226 }
227
228 impl From<Box<str>> for String {
229 #[check(ghost)]
230 #[ensures(result@ == s@)]
231 fn from(s: Box<str>) -> Self;
232 }
233
234 impl From<String> for Box<str> {
235 #[check(ghost)]
236 #[ensures(result@ == s@)]
237 fn from(s: String) -> Self;
238 }
239
240 impl From<&str> for String {
241 #[check(ghost)]
242 #[ensures(result@ == s@)]
243 fn from(s: &str) -> Self;
244 }
245
246 impl From<&mut str> for String {
247 #[check(ghost)]
248 #[ensures(result@ == s@ && ^s == *s)]
249 fn from(s: &mut String) -> Self;
250 }
251
252 impl From<&mut str> for Box<str> {
253 #[check(ghost)]
254 #[ensures(result@ == s@ && ^s == *s)]
255 fn from(s: &mut str) -> Self;
256 }
257
258 impl From<char> for String {
259 #[check(ghost)]
260 #[ensures(result@ == seq![c])]
261 fn from(c: char) -> Self;
262 }
263
264 impl From<String> for Vec<u8> {
265 #[check(ghost)]
266 #[ensures(result@ == s@.to_bytes())]
267 fn from(s: String) -> Self;
268 }
269
270 impl From<&str> for Vec<u8> {
271 #[check(ghost)]
272 #[ensures(result@ == s@.to_bytes())]
273 fn from(s: &str) -> Self;
274 }
275}
276
277macro_rules! spec_from {
278 ($src:ty => $tgt:ty) => {
279 extern_spec! {
280 impl From<$src> for $tgt {
281 #[check(ghost)]
282 #[ensures(result == (small as Self))]
283 fn from(small: $src) -> Self {
284 small as Self
285 }
286 }
287 }
288 };
289}
290
291spec_from!(bool => u8);
292spec_from!(bool => u16);
293spec_from!(bool => u32);
294spec_from!(bool => u64);
295spec_from!(bool => u128);
296spec_from!(bool => usize);
297spec_from!(bool => i8);
298spec_from!(bool => i16);
299spec_from!(bool => i32);
300spec_from!(bool => i64);
301spec_from!(bool => i128);
302spec_from!(bool => isize);
303
304spec_from!(u8 => u16);
306spec_from!(u8 => u32);
307spec_from!(u8 => u64);
308spec_from!(u8 => u128);
309spec_from!(u8 => usize);
310spec_from!(u16 => u32);
311spec_from!(u16 => u64);
312spec_from!(u16 => u128);
313spec_from!(u16 => usize);
314spec_from!(u32 => u64);
315spec_from!(u32 => u128);
316spec_from!(u64 => u128);
317
318spec_from!(i8 => i16);
320spec_from!(i8 => i32);
321spec_from!(i8 => i64);
322spec_from!(i8 => i128);
323spec_from!(i8 => isize);
324spec_from!(i16 => i32);
325spec_from!(i16 => i64);
326spec_from!(i16 => i128);
327spec_from!(i16 => isize);
328spec_from!(i32 => i64);
329spec_from!(i32 => i128);
330spec_from!(i64 => i128);
331
332spec_from!(u8 => i16);
334spec_from!(u8 => i32);
335spec_from!(u8 => i64);
336spec_from!(u8 => i128);
337spec_from!(u8 => isize);
338spec_from!(u16 => i32);
339spec_from!(u16 => i64);
340spec_from!(u16 => i128);
341spec_from!(u32 => i64);
342spec_from!(u32 => i128);
343spec_from!(u64 => i128);