1#![allow(unused_imports)]
2
3use super::prelude::*;
4
5verus! {
6
7pub open spec fn is_power_2(n: int) -> bool
10 decreases n,
11{
12 if n <= 0 {
13 false
14 } else if n == 1 {
15 true
16 } else {
17 n % 2 == 0 && is_power_2(n / 2)
18 }
19}
20
21pub open spec fn valid_layout(size: usize, align: usize) -> bool {
23 is_power_2(align as int) && size <= isize::MAX as int - (isize::MAX as int % align as int)
24}
25
26#[cfg_attr(not(verus_verify_core), deprecated = "is_sized is now defunct; lemmas that require V to be sized should now use the trait bound `V: Sized` instead of is_sized<V>")]
27pub uninterp spec fn is_sized<V: ?Sized>() -> bool;
28
29pub uninterp spec fn size_of<V>() -> nat;
30
31pub uninterp spec fn align_of<V>() -> nat;
32
33#[verifier::inline]
47pub open spec fn size_of_as_usize<V>() -> usize
48 recommends
49 size_of::<V>() as usize as int == size_of::<V>(),
50{
51 size_of::<V>() as usize
52}
53
54#[verifier::inline]
55pub open spec fn align_of_as_usize<V>() -> usize
56 recommends
57 align_of::<V>() as usize as int == align_of::<V>(),
58{
59 align_of::<V>() as usize
60}
61
62#[verifier::when_used_as_spec(size_of_as_usize)]
63pub assume_specification<V>[ core::mem::size_of::<V> ]() -> (u: usize)
64 ensures
65 u as nat == size_of::<V>(),
66 opens_invariants none
67 no_unwind
68;
69
70#[verifier::when_used_as_spec(align_of_as_usize)]
71pub assume_specification<V>[ core::mem::align_of::<V> ]() -> (u: usize)
72 ensures
73 u as nat == align_of::<V>(),
74 opens_invariants none
75 no_unwind
76;
77
78#[verifier::external_body]
87#[inline(always)]
88pub exec fn layout_for_type_is_valid<V>()
89 ensures
90 valid_layout(size_of::<V>() as usize, align_of::<V>() as usize),
91 size_of::<V>() as usize as nat == size_of::<V>(),
92 align_of::<V>() as usize as nat == align_of::<V>(),
93 align_of::<V>() != 0,
94 size_of::<V>() % align_of::<V>() == 0,
95 opens_invariants none
96 no_unwind
97{
98}
99
100pub broadcast axiom fn layout_of_primitives()
105 ensures
106 #![trigger size_of::<bool>()]
107 #![trigger size_of::<char>()]
108 #![trigger size_of::<u8>()]
109 #![trigger size_of::<i8>()]
110 #![trigger size_of::<u16>()]
111 #![trigger size_of::<i16>()]
112 #![trigger size_of::<u32>()]
113 #![trigger size_of::<i32>()]
114 #![trigger size_of::<u64>()]
115 #![trigger size_of::<i64>()]
116 #![trigger size_of::<usize>()]
117 #![trigger size_of::<isize>()]
118 size_of::<bool>() == 1,
119 size_of::<char>() == 4,
120 size_of::<u8>() == size_of::<i8>() == 1,
121 size_of::<u16>() == size_of::<i16>() == 2,
122 size_of::<u32>() == size_of::<i32>() == 4,
123 size_of::<u64>() == size_of::<i64>() == 8,
124 size_of::<u128>() == size_of::<i128>() == 16,
125 size_of::<usize>() == size_of::<isize>(),
126 size_of::<usize>() * 8 == usize::BITS,
127;
128
129pub broadcast axiom fn layout_of_unit_tuple()
131 ensures
132 #![trigger size_of::<()>()]
133 #![trigger align_of::<()>()]
134 size_of::<()>() == 0,
135 align_of::<()>() == 1,
136;
137
138pub broadcast axiom fn layout_of_references_and_pointers<T: ?Sized>()
140 ensures
141 #![trigger size_of::<*mut T>()]
142 #![trigger size_of::<*const T>()]
143 #![trigger size_of::<&T>()]
144 #![trigger align_of::<*mut T>()]
145 #![trigger align_of::<*const T>()]
146 #![trigger align_of::<&T>()]
147 size_of::<*mut T>() == size_of::<*const T>() == size_of::<&T>(),
148 align_of::<*mut T>() == align_of::<*const T>() == align_of::<&T>(),
149;
150
151pub broadcast axiom fn layout_of_references_and_pointers_for_sized_types<T: Sized>()
154 ensures
155 #![trigger size_of::<*mut T>()]
156 #![trigger align_of::<*mut T>()]
157 size_of::<*mut T>() == size_of::<usize>(),
158 align_of::<*mut T>() == align_of::<usize>(),
159;
160
161pub broadcast group group_layout_axioms {
162 layout_of_primitives,
163 layout_of_unit_tuple,
164 layout_of_references_and_pointers,
165 layout_of_references_and_pointers_for_sized_types,
166}
167
168}