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
114#[cfg(feature = "std")]
115extern_spec! {
116 impl<T> From<T> for Box<T> {
117 #[check(ghost)]
118 #[ensures(*result == x)]
119 fn from(x: T) -> Self;
120 }
121
122 impl<T: Clone> From<&[T]> for Box<[T]>
123 {
124 #[ensures(result@.len() == s@.len())]
126 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
127 fn from(s: &[T]) -> Self;
128 }
130
131 impl<T: Clone> From<&mut [T]> for Box<[T]>
132 {
133 #[ensures(result@.len() == s@.len())]
135 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
136 #[ensures(^s == *s)]
137 fn from(s: &mut [T]) -> Self {
138 Box::<[T]>::from(&*s)
139 }
140 }
141
142 impl<T, const N: usize> From<[T; N]> for Box<[T]> {
143 #[check(ghost)]
144 #[ensures(result@ == s@)]
145 fn from(s: [T; N]) -> Self {
146 Box::new(s)
147 }
148 }
149
150 impl<T: Clone> From<&[T]> for Vec<T>
151 {
152 #[ensures(result@.len() == s@.len())]
154 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
155 fn from(s: &[T]) -> Self {
156 s.to_vec()
157 }
158 }
159
160 impl<T: Clone> From<&mut [T]> for Vec<T>
161 {
162 #[ensures(result@.len() == s@.len())]
164 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
165 #[ensures(^s == *s)]
166 fn from(s: &mut [T]) -> Self {
167 s.to_vec()
168 }
169 }
170
171 impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
172 #[check(ghost)]
173 #[ensures(result@ == s@)]
174 fn from(s: Box<[T], A>) -> Self {
175 s.into_vec()
176 }
177 }
178
179 impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
180 #[ensures(result@.len() == N@)]
182 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
183 fn from(s: &[T; N]) -> Self {
184 Vec::<T>::from(s.as_slice())
185 }
186 }
187
188 impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
189 #[ensures(result@.len() == N@)]
191 #[ensures(forall<i> 0 <= i && i < s@.len() ==> <T as Clone>::clone.postcondition((&s@[i],), result@[i]))]
192 #[ensures(^s == *s)]
193 fn from(s: &mut [T; N]) -> Self {
194 Vec::<T>::from(s.as_mut_slice())
195 }
196 }
197
198 impl<T, const N: usize> From<[T; N]> for Vec<T> {
199 #[check(ghost)]
200 #[ensures(result@ == s@)]
201 fn from(s: [T; N]) -> Self {
202 <[T]>::into_vec(Box::new(s))
203 }
204 }
205
206 impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
207 #[check(ghost)]
208 #[ensures(result@ == v@)]
209 fn from(v: Vec<T, A>) -> Self {
210 v.into_boxed_slice()
211 }
212 }
213
214 impl From<&String> for String {
215 #[check(ghost)]
216 #[ensures(result@ == s@)]
217 fn from(s: &String) -> Self;
218 }
219
220 impl From<Box<str>> for String {
221 #[check(ghost)]
222 #[ensures(result@ == s@)]
223 fn from(s: Box<str>) -> Self;
224 }
225
226 impl From<String> for Box<str> {
227 #[check(ghost)]
228 #[ensures(result@ == s@)]
229 fn from(s: String) -> Self;
230 }
231
232 impl From<&str> for String {
233 #[check(ghost)]
234 #[ensures(result@ == s@)]
235 fn from(s: &str) -> Self;
236 }
237
238 impl From<&mut str> for String {
239 #[check(ghost)]
240 #[ensures(result@ == s@ && ^s == *s)]
241 fn from(s: &mut String) -> Self;
242 }
243
244 impl From<&mut str> for Box<str> {
245 #[check(ghost)]
246 #[ensures(result@ == s@ && ^s == *s)]
247 fn from(s: &mut str) -> Self;
248 }
249
250 impl From<char> for String {
251 #[check(ghost)]
252 #[ensures(result@ == seq![c])]
253 fn from(c: char) -> Self;
254 }
255
256 impl From<String> for Vec<u8> {
257 #[check(ghost)]
258 #[ensures(result@ == s@.to_bytes())]
259 fn from(s: String) -> Self;
260 }
261
262 impl From<&str> for Vec<u8> {
263 #[check(ghost)]
264 #[ensures(result@ == s@.to_bytes())]
265 fn from(s: &str) -> Self;
266 }
267}
268
269macro_rules! spec_from {
270 ($src:ty => $tgt:ty) => {
271 extern_spec! {
272 impl From<$src> for $tgt {
273 #[check(ghost)]
274 #[ensures(result == (small as Self))]
275 fn from(small: $src) -> Self {
276 small as Self
277 }
278 }
279 }
280 };
281}
282
283spec_from!(bool => u8);
284spec_from!(bool => u16);
285spec_from!(bool => u32);
286spec_from!(bool => u64);
287spec_from!(bool => u128);
288spec_from!(bool => usize);
289spec_from!(bool => i8);
290spec_from!(bool => i16);
291spec_from!(bool => i32);
292spec_from!(bool => i64);
293spec_from!(bool => i128);
294spec_from!(bool => isize);
295
296spec_from!(u8 => u16);
298spec_from!(u8 => u32);
299spec_from!(u8 => u64);
300spec_from!(u8 => u128);
301spec_from!(u8 => usize);
302spec_from!(u16 => u32);
303spec_from!(u16 => u64);
304spec_from!(u16 => u128);
305spec_from!(u16 => usize);
306spec_from!(u32 => u64);
307spec_from!(u32 => u128);
308spec_from!(u64 => u128);
309
310spec_from!(i8 => i16);
312spec_from!(i8 => i32);
313spec_from!(i8 => i64);
314spec_from!(i8 => i128);
315spec_from!(i8 => isize);
316spec_from!(i16 => i32);
317spec_from!(i16 => i64);
318spec_from!(i16 => i128);
319spec_from!(i16 => isize);
320spec_from!(i32 => i64);
321spec_from!(i32 => i128);
322spec_from!(i64 => i128);
323
324spec_from!(u8 => i16);
326spec_from!(u8 => i32);
327spec_from!(u8 => i64);
328spec_from!(u8 => i128);
329spec_from!(u8 => isize);
330spec_from!(u16 => i32);
331spec_from!(u16 => i64);
332spec_from!(u16 => i128);
333spec_from!(u32 => i64);
334spec_from!(u32 => i128);
335spec_from!(u64 => i128);