1#[cfg(feature = "nightly")]
2use crate::logic::ops::{DerefLogic, DerefMutLogic};
3#[cfg(creusot)]
4use crate::resolve::structural_resolve;
5use crate::{invariant::*, prelude::*};
6#[cfg(feature = "nightly")]
7use std::alloc::Allocator;
8
9#[cfg(creusot)]
10use std::ops::{Deref, DerefMut};
11
12#[cfg(feature = "nightly")]
13impl<T: DeepModel + ?Sized, A: Allocator> DeepModel for Box<T, A> {
14 type DeepModelTy = Box<T::DeepModelTy>;
15 #[logic(open, inline)]
16 fn deep_model(self) -> Self::DeepModelTy {
17 Box::new((*self).deep_model())
18 }
19}
20
21#[cfg(feature = "nightly")]
22impl<T: View + ?Sized, A: Allocator> View for Box<T, A> {
23 type ViewTy = T::ViewTy;
24 #[logic(open, inline)]
25 fn view(self) -> Self::ViewTy {
26 (*self).view()
27 }
28}
29
30#[cfg(feature = "nightly")]
31impl<T: ?Sized, A: Allocator> Resolve for Box<T, A> {
32 #[logic(open, prophetic, inline)]
33 #[creusot::trusted_trivial_if_param_trivial]
34 fn resolve(self) -> bool {
35 true
36 }
37
38 #[trusted]
39 #[logic(prophetic)]
40 #[requires(structural_resolve(self))]
41 #[ensures(self.resolve())]
42 fn resolve_coherence(self) {}
43}
44
45#[cfg(feature = "nightly")]
46impl<T: ?Sized, A: Allocator> Invariant for Box<T, A> {
47 #[logic(open, prophetic)]
48 #[creusot::trusted_trivial_if_param_trivial]
49 fn invariant(self) -> bool {
50 inv(*self)
51 }
52}
53
54#[cfg(feature = "nightly")]
55impl<T, A: Allocator> DerefLogic for Box<T, A> {
56 #[logic]
57 #[builtin("identity")]
58 fn deref_logic(&self) -> &T {
59 dead
60 }
61}
62
63#[cfg(feature = "nightly")]
64impl<T, A: Allocator> DerefMutLogic for Box<T, A> {
65 #[logic]
66 #[builtin("identity")]
67 fn deref_mut_logic(&mut self) -> &mut T {
68 dead
69 }
70}
71
72#[logic]
73#[builtin("identity")]
74pub fn new_box_logic<T>(val: T) -> Box<T> {
75 let _ = val;
76 dead
77}
78
79extern_spec! {
80 impl<T> Box<T> {
81 #[check(ghost)]
82 #[logic_alias(new_box_logic(val))]
83 fn new(val: T) -> Self;
84 }
85
86 impl<T: ?Sized> Box<T> {
87 #[check(ghost)]
90 #[requires(false)]
91 unsafe fn from_raw(raw: *mut T) -> Box<T>;
92
93 #[check(ghost)]
94 fn into_raw(self) -> *const T;
95 }
96
97 impl<T, A: Allocator> Box<T, A> {
98 #[check(ghost)]
99 #[ensures(**self == *result)]
100 #[ensures(*^self == ^result)]
101 fn as_mut(&mut self) -> &mut T;
102
103 #[check(ghost)]
104 #[ensures(**self == *result)]
105 fn as_ref(&self) -> &T;
106
107 #[check(ghost)]
108 #[ensures(*result == *b)]
109 fn leak<'a>(b: Box<T, A>) -> &'a mut T
110 where
111 A: 'a;
112 }
113
114 impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
115 #[ensures(T::clone.postcondition((&**self,), *result))]
116 fn clone(&self) -> Box<T, A>;
117 }
118
119 impl<T, A: Allocator> Deref for Box<T, A> {
120 #[check(ghost)]
121 #[logic_alias(self.deref_logic())]
122 fn deref(&self) -> &T {
123 &**self
124 }
125 }
126
127 impl<T, A: Allocator> DerefMut for Box<T, A> {
128 #[check(ghost)]
129 #[logic_alias(self.deref_mut_logic())]
130 fn deref_mut(&mut self) -> &mut T {
131 &mut **self
132 }
133 }
134
135 impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
136 #[ensures(match result {
137 Ok(arr) => slice@.len() == N@ && arr@ == slice@,
138 Err(orig) => slice@.len() != N@ && orig@ == slice@
139 })]
140 fn try_from(slice: Box<[T]>) -> Result<Self, Box<[T]>>;
141 }
142
143 impl<T, const N: usize> TryFrom<Vec<T>> for Box<[T; N]> {
144 #[ensures(match result {
145 Ok(arr) => slice@.len() == N@ && arr@ == slice@,
146 Err(orig) => slice@.len() != N@ && orig@ == slice@,
147 })]
148 fn try_from(slice: Vec<T>) -> Result<Self, Vec<T>>;
149 }
150}
151
152#[cfg(not(feature = "nightly"))]
154impl<T: DeepModel + ?Sized> DeepModel for Box<T> {
155 type DeepModelTy = Box<T::DeepModelTy>;
156}
157
158#[cfg(not(feature = "nightly"))]
159impl<T: ?Sized> Invariant for Box<T> {}
160
161#[cfg(not(feature = "nightly"))]
162impl<T: ?Sized> Resolve for Box<T> {}