Coverage Report

Created: 2026-09-03 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gimli/src/read/util.rs
Line
Count
Source
1
#[cfg(feature = "read")]
2
use alloc::boxed::Box;
3
#[cfg(feature = "read")]
4
use alloc::vec::Vec;
5
use core::fmt;
6
use core::mem::MaybeUninit;
7
use core::ops;
8
use core::ptr;
9
use core::slice;
10
11
mod sealed {
12
    /// # Safety
13
    /// Implementer must not modify the content in storage.
14
    pub unsafe trait Sealed {
15
        type Storage;
16
17
        fn new_storage() -> Self::Storage;
18
19
5.00k
        fn grow(_storage: &mut Self::Storage, _additional: usize) -> Result<(), CapacityFull> {
20
5.00k
            Err(CapacityFull)
21
5.00k
        }
<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]> as gimli::read::util::sealed::Sealed>::grow
Line
Count
Source
19
3.73k
        fn grow(_storage: &mut Self::Storage, _additional: usize) -> Result<(), CapacityFull> {
20
3.73k
            Err(CapacityFull)
21
3.73k
        }
<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192] as gimli::read::util::sealed::Sealed>::grow
Line
Count
Source
19
1.27k
        fn grow(_storage: &mut Self::Storage, _additional: usize) -> Result<(), CapacityFull> {
20
1.27k
            Err(CapacityFull)
21
1.27k
        }
22
    }
23
24
    #[derive(Clone, Copy, Debug)]
25
    pub struct CapacityFull;
26
}
27
28
use sealed::*;
29
30
/// Marker trait for types that can be used as backing storage when a growable array type is needed.
31
///
32
/// This trait is sealed and cannot be implemented for types outside this crate.
33
pub trait ArrayLike: Sealed {
34
    /// Type of the elements being stored.
35
    type Item;
36
37
    #[doc(hidden)]
38
    fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<Self::Item>];
39
40
    #[doc(hidden)]
41
    fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<Self::Item>];
42
}
43
44
// SAFETY: does not modify the content in storage.
45
unsafe impl<T, const N: usize> Sealed for [T; N] {
46
    type Storage = [MaybeUninit<T>; N];
47
48
69.5k
    fn new_storage() -> Self::Storage {
49
        // SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
50
69.5k
        unsafe { MaybeUninit::uninit().assume_init() }
51
69.5k
    }
52
}
53
54
impl<T, const N: usize> ArrayLike for [T; N] {
55
    type Item = T;
56
57
225k
    fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
58
225k
        storage
59
225k
    }
60
61
1.51M
    fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
62
1.51M
        storage
63
1.51M
    }
64
}
65
66
// SAFETY: does not modify the content in storage.
67
#[cfg(feature = "read")]
68
unsafe impl<T, const N: usize> Sealed for Box<[T; N]> {
69
    type Storage = Box<[MaybeUninit<T>; N]>;
70
71
6.67k
    fn new_storage() -> Self::Storage {
72
        // SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
73
6.67k
        Box::new(unsafe { MaybeUninit::uninit().assume_init() })
74
6.67k
    }
75
}
76
77
#[cfg(feature = "read")]
78
impl<T, const N: usize> ArrayLike for Box<[T; N]> {
79
    type Item = T;
80
81
810k
    fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
82
810k
        &storage[..]
83
810k
    }
84
85
1.26M
    fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
86
1.26M
        &mut storage[..]
87
1.26M
    }
88
}
89
90
#[cfg(feature = "read")]
91
unsafe impl<T> Sealed for Vec<T> {
92
    type Storage = Box<[MaybeUninit<T>]>;
93
94
    fn new_storage() -> Self::Storage {
95
        Box::new([])
96
    }
97
98
    fn grow(storage: &mut Self::Storage, additional: usize) -> Result<(), CapacityFull> {
99
        let mut vec: Vec<_> = core::mem::replace(storage, Box::new([])).into();
100
        vec.reserve(additional);
101
        // SAFETY: This is a `Vec` of `MaybeUninit`.
102
        unsafe { vec.set_len(vec.capacity()) };
103
        *storage = vec.into_boxed_slice();
104
        Ok(())
105
    }
106
}
107
108
#[cfg(feature = "read")]
109
impl<T> ArrayLike for Vec<T> {
110
    type Item = T;
111
112
    fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
113
        storage
114
    }
115
116
    fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
117
        storage
118
    }
119
}
120
121
pub(crate) struct ArrayVec<A: ArrayLike> {
122
    storage: A::Storage,
123
    len: usize,
124
}
125
126
impl<A: ArrayLike> ArrayVec<A> {
127
76.1k
    pub fn new() -> Self {
128
76.1k
        Self {
129
76.1k
            storage: A::new_storage(),
130
76.1k
            len: 0,
131
76.1k
        }
132
76.1k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]>>::new
Line
Count
Source
127
69.5k
    pub fn new() -> Self {
128
69.5k
        Self {
129
69.5k
            storage: A::new_storage(),
130
69.5k
            len: 0,
131
69.5k
        }
132
69.5k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>>>::new
Line
Count
Source
127
6.67k
    pub fn new() -> Self {
128
6.67k
        Self {
129
6.67k
            storage: A::new_storage(),
130
6.67k
            len: 0,
131
6.67k
        }
132
6.67k
    }
133
134
114k
    pub fn clear(&mut self) {
135
114k
        let ptr: *mut [A::Item] = &mut **self;
136
        // Set length first so the type invariant is upheld even if `drop_in_place` panicks.
137
114k
        self.len = 0;
138
        // SAFETY: `ptr` contains valid elements only and we "forget" them by setting the length.
139
114k
        unsafe { ptr::drop_in_place(ptr) };
140
114k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]>>::clear
Line
Count
Source
134
69.5k
    pub fn clear(&mut self) {
135
69.5k
        let ptr: *mut [A::Item] = &mut **self;
136
        // Set length first so the type invariant is upheld even if `drop_in_place` panicks.
137
69.5k
        self.len = 0;
138
        // SAFETY: `ptr` contains valid elements only and we "forget" them by setting the length.
139
69.5k
        unsafe { ptr::drop_in_place(ptr) };
140
69.5k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>>>::clear
Line
Count
Source
134
44.5k
    pub fn clear(&mut self) {
135
44.5k
        let ptr: *mut [A::Item] = &mut **self;
136
        // Set length first so the type invariant is upheld even if `drop_in_place` panicks.
137
44.5k
        self.len = 0;
138
        // SAFETY: `ptr` contains valid elements only and we "forget" them by setting the length.
139
44.5k
        unsafe { ptr::drop_in_place(ptr) };
140
44.5k
    }
141
142
837k
    pub fn try_push(&mut self, value: A::Item) -> Result<(), CapacityFull> {
143
837k
        let mut storage = A::as_mut_slice(&mut self.storage);
144
837k
        if self.len >= storage.len() {
145
4.80k
            A::grow(&mut self.storage, 1)?;
146
0
            storage = A::as_mut_slice(&mut self.storage);
147
832k
        }
148
149
832k
        storage[self.len] = MaybeUninit::new(value);
150
832k
        self.len += 1;
151
832k
        Ok(())
152
837k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]>>::try_push
Line
Count
Source
142
772k
    pub fn try_push(&mut self, value: A::Item) -> Result<(), CapacityFull> {
143
772k
        let mut storage = A::as_mut_slice(&mut self.storage);
144
772k
        if self.len >= storage.len() {
145
1.27k
            A::grow(&mut self.storage, 1)?;
146
0
            storage = A::as_mut_slice(&mut self.storage);
147
771k
        }
148
149
771k
        storage[self.len] = MaybeUninit::new(value);
150
771k
        self.len += 1;
151
771k
        Ok(())
152
772k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>>>::try_push
Line
Count
Source
142
65.2k
    pub fn try_push(&mut self, value: A::Item) -> Result<(), CapacityFull> {
143
65.2k
        let mut storage = A::as_mut_slice(&mut self.storage);
144
65.2k
        if self.len >= storage.len() {
145
3.53k
            A::grow(&mut self.storage, 1)?;
146
0
            storage = A::as_mut_slice(&mut self.storage);
147
61.6k
        }
148
149
61.6k
        storage[self.len] = MaybeUninit::new(value);
150
61.6k
        self.len += 1;
151
61.6k
        Ok(())
152
65.2k
    }
153
154
4.30k
    pub fn try_insert(&mut self, index: usize, element: A::Item) -> Result<(), CapacityFull> {
155
4.30k
        assert!(index <= self.len);
156
157
4.30k
        let mut storage = A::as_mut_slice(&mut self.storage);
158
4.30k
        if self.len >= storage.len() {
159
206
            A::grow(&mut self.storage, 1)?;
160
0
            storage = A::as_mut_slice(&mut self.storage);
161
4.10k
        }
162
163
        // SAFETY: storage[index] is filled later.
164
4.10k
        unsafe {
165
4.10k
            let p = storage.as_mut_ptr().add(index);
166
4.10k
            core::ptr::copy(p as *const _, p.add(1), self.len - index);
167
4.10k
        }
168
4.10k
        storage[index] = MaybeUninit::new(element);
169
4.10k
        self.len += 1;
170
4.10k
        Ok(())
171
4.30k
    }
172
173
14.9k
    pub fn pop(&mut self) -> Option<A::Item> {
174
14.9k
        if self.len == 0 {
175
0
            None
176
        } else {
177
14.9k
            self.len -= 1;
178
            // SAFETY: this element is valid and we "forget" it by setting the length.
179
14.9k
            Some(unsafe { A::as_slice(&self.storage)[self.len].as_ptr().read() })
180
        }
181
14.9k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]>>::pop
Line
Count
Source
173
8.33k
    pub fn pop(&mut self) -> Option<A::Item> {
174
8.33k
        if self.len == 0 {
175
0
            None
176
        } else {
177
8.33k
            self.len -= 1;
178
            // SAFETY: this element is valid and we "forget" it by setting the length.
179
8.33k
            Some(unsafe { A::as_slice(&self.storage)[self.len].as_ptr().read() })
180
        }
181
8.33k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>>>::pop
Line
Count
Source
173
6.61k
    pub fn pop(&mut self) -> Option<A::Item> {
174
6.61k
        if self.len == 0 {
175
0
            None
176
        } else {
177
6.61k
            self.len -= 1;
178
            // SAFETY: this element is valid and we "forget" it by setting the length.
179
6.61k
            Some(unsafe { A::as_slice(&self.storage)[self.len].as_ptr().read() })
180
        }
181
6.61k
    }
182
183
8.33k
    pub fn swap_remove(&mut self, index: usize) -> A::Item {
184
8.33k
        assert!(self.len > 0);
185
8.33k
        A::as_mut_slice(&mut self.storage).swap(index, self.len - 1);
186
8.33k
        self.pop().unwrap()
187
8.33k
    }
188
}
189
190
#[cfg(feature = "read")]
191
impl<T> ArrayVec<Vec<T>> {
192
    pub fn into_vec(mut self) -> Vec<T> {
193
        let len = core::mem::replace(&mut self.len, 0);
194
        let storage = core::mem::replace(&mut self.storage, Box::new([]));
195
        let slice = Box::leak(storage);
196
        debug_assert!(len <= slice.len());
197
        // SAFETY: valid elements.
198
        unsafe { Vec::from_raw_parts(slice.as_mut_ptr() as *mut T, len, slice.len()) }
199
    }
200
}
201
202
impl<A: ArrayLike> Drop for ArrayVec<A> {
203
76.1k
    fn drop(&mut self) {
204
76.1k
        self.clear();
205
76.1k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]> as core::ops::drop::Drop>::drop
Line
Count
Source
203
69.5k
    fn drop(&mut self) {
204
69.5k
        self.clear();
205
69.5k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>> as core::ops::drop::Drop>::drop
Line
Count
Source
203
6.67k
    fn drop(&mut self) {
204
6.67k
        self.clear();
205
6.67k
    }
206
}
207
208
impl<A: ArrayLike> Default for ArrayVec<A> {
209
76.1k
    fn default() -> Self {
210
76.1k
        Self::new()
211
76.1k
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]> as core::default::Default>::default
Line
Count
Source
209
69.5k
    fn default() -> Self {
210
69.5k
        Self::new()
211
69.5k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>> as core::default::Default>::default
Line
Count
Source
209
6.67k
    fn default() -> Self {
210
6.67k
        Self::new()
211
6.67k
    }
212
}
213
214
impl<A: ArrayLike> ops::Deref for ArrayVec<A> {
215
    type Target = [A::Item];
216
217
1.02M
    fn deref(&self) -> &[A::Item] {
218
1.02M
        let slice = &A::as_slice(&self.storage);
219
1.02M
        debug_assert!(self.len <= slice.len());
220
        // SAFETY: valid elements.
221
1.02M
        unsafe { slice::from_raw_parts(slice.as_ptr() as _, self.len) }
222
1.02M
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]> as core::ops::deref::Deref>::deref
Line
Count
Source
217
217k
    fn deref(&self) -> &[A::Item] {
218
217k
        let slice = &A::as_slice(&self.storage);
219
217k
        debug_assert!(self.len <= slice.len());
220
        // SAFETY: valid elements.
221
217k
        unsafe { slice::from_raw_parts(slice.as_ptr() as _, self.len) }
222
217k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>> as core::ops::deref::Deref>::deref
Line
Count
Source
217
803k
    fn deref(&self) -> &[A::Item] {
218
803k
        let slice = &A::as_slice(&self.storage);
219
803k
        debug_assert!(self.len <= slice.len());
220
        // SAFETY: valid elements.
221
803k
        unsafe { slice::from_raw_parts(slice.as_ptr() as _, self.len) }
222
803k
    }
223
}
224
225
impl<A: ArrayLike> ops::DerefMut for ArrayVec<A> {
226
1.92M
    fn deref_mut(&mut self) -> &mut [A::Item] {
227
1.92M
        let slice = &mut A::as_mut_slice(&mut self.storage);
228
1.92M
        debug_assert!(self.len <= slice.len());
229
        // SAFETY: valid elements.
230
1.92M
        unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr() as _, self.len) }
231
1.92M
    }
<gimli::read::util::ArrayVec<[(gimli::common::Register, gimli::read::cfi::RegisterRule<usize>); 192]> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
226
730k
    fn deref_mut(&mut self) -> &mut [A::Item] {
227
730k
        let slice = &mut A::as_mut_slice(&mut self.storage);
228
730k
        debug_assert!(self.len <= slice.len());
229
        // SAFETY: valid elements.
230
730k
        unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr() as _, self.len) }
231
730k
    }
<gimli::read::util::ArrayVec<alloc::boxed::Box<[gimli::read::cfi::UnwindTableRow<usize>; 4]>> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
226
1.19M
    fn deref_mut(&mut self) -> &mut [A::Item] {
227
1.19M
        let slice = &mut A::as_mut_slice(&mut self.storage);
228
1.19M
        debug_assert!(self.len <= slice.len());
229
        // SAFETY: valid elements.
230
1.19M
        unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr() as _, self.len) }
231
1.19M
    }
232
}
233
234
impl<A: ArrayLike> Clone for ArrayVec<A>
235
where
236
    A::Item: Clone,
237
{
238
31.6k
    fn clone(&self) -> Self {
239
31.6k
        let mut new = Self::default();
240
432k
        for value in &**self {
241
432k
            new.try_push(value.clone()).unwrap();
242
432k
        }
243
31.6k
        new
244
31.6k
    }
245
}
246
247
impl<A: ArrayLike> PartialEq for ArrayVec<A>
248
where
249
    A::Item: PartialEq,
250
{
251
    fn eq(&self, other: &Self) -> bool {
252
        **self == **other
253
    }
254
}
255
256
impl<A: ArrayLike> Eq for ArrayVec<A> where A::Item: Eq {}
257
258
impl<A: ArrayLike> fmt::Debug for ArrayVec<A>
259
where
260
    A::Item: fmt::Debug,
261
{
262
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
263
        fmt::Debug::fmt(&**self, f)
264
    }
265
}