Coverage Report

Created: 2025-12-10 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wgpu/naga/src/arena/mod.rs
Line
Count
Source
1
/*! The [`Arena`], [`UniqueArena`], and [`Handle`] types.
2
3
To improve translator performance and reduce memory usage, most structures are
4
stored in an [`Arena`]. An `Arena<T>` stores a series of `T` values, indexed by
5
[`Handle<T>`] values, which are just wrappers around integer indexes.
6
For example, a `Function`'s expressions are stored in an `Arena<Expression>`,
7
and compound expressions refer to their sub-expressions via `Handle<Expression>`
8
values.
9
10
A [`UniqueArena`] is just like an `Arena`, except that it stores only a single
11
instance of each value. The value type must implement `Eq` and `Hash`. Like an
12
`Arena`, inserting a value into a `UniqueArena` returns a `Handle` which can be
13
used to efficiently access the value, without a hash lookup. Inserting a value
14
multiple times returns the same `Handle`.
15
16
If the `span` feature is enabled, both `Arena` and `UniqueArena` can associate a
17
source code span with each element.
18
19
[`Handle<T>`]: Handle
20
*/
21
22
mod handle;
23
mod handle_set;
24
mod handlevec;
25
mod range;
26
mod unique_arena;
27
28
pub use handle::{BadHandle, Handle};
29
pub(crate) use handle_set::HandleSet;
30
pub(crate) use handlevec::HandleVec;
31
pub use range::{BadRangeError, Range};
32
pub use unique_arena::UniqueArena;
33
34
use alloc::vec::Vec;
35
use core::{fmt, ops};
36
37
use crate::Span;
38
39
use handle::Index;
40
41
/// An arena holding some kind of component (e.g., type, constant,
42
/// instruction, etc.) that can be referenced.
43
///
44
/// Adding new items to the arena produces a strongly-typed [`Handle`].
45
/// The arena can be indexed using the given handle to obtain
46
/// a reference to the stored item.
47
#[derive(Clone)]
48
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
49
#[cfg_attr(feature = "serialize", serde(transparent))]
50
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
51
#[cfg_attr(test, derive(PartialEq))]
52
pub struct Arena<T> {
53
    /// Values of this arena.
54
    data: Vec<T>,
55
    #[cfg_attr(feature = "serialize", serde(skip))]
56
    span_info: Vec<Span>,
57
}
58
59
impl<T> Default for Arena<T> {
60
802
    fn default() -> Self {
61
802
        Self::new()
62
802
    }
<naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode> as core::default::Default>::default
Line
Count
Source
60
168
    fn default() -> Self {
61
168
        Self::new()
62
168
    }
<naga::arena::Arena<naga::ir::Expression> as core::default::Default>::default
Line
Count
Source
60
65
    fn default() -> Self {
61
65
        Self::new()
62
65
    }
<naga::arena::Arena<naga::ir::LocalVariable> as core::default::Default>::default
Line
Count
Source
60
2
    fn default() -> Self {
61
2
        Self::new()
62
2
    }
<naga::arena::Arena<naga::ir::GlobalVariable> as core::default::Default>::default
Line
Count
Source
60
63
    fn default() -> Self {
61
63
        Self::new()
62
63
    }
<naga::arena::Arena<naga::ir::Constant> as core::default::Default>::default
Line
Count
Source
60
63
    fn default() -> Self {
61
63
        Self::new()
62
63
    }
<naga::arena::Arena<naga::ir::Function> as core::default::Default>::default
Line
Count
Source
60
63
    fn default() -> Self {
61
63
        Self::new()
62
63
    }
<naga::arena::Arena<naga::ir::Override> as core::default::Default>::default
Line
Count
Source
60
63
    fn default() -> Self {
61
63
        Self::new()
62
63
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Expression> as core::default::Default>::default
Line
Count
Source
60
105
    fn default() -> Self {
61
105
        Self::new()
62
105
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl> as core::default::Default>::default
Line
Count
Source
60
105
    fn default() -> Self {
61
105
        Self::new()
62
105
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Type> as core::default::Default>::default
Line
Count
Source
60
105
    fn default() -> Self {
61
105
        Self::new()
62
105
    }
63
}
64
65
impl<T: fmt::Debug> fmt::Debug for Arena<T> {
66
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67
0
        f.debug_map().entries(self.iter()).finish()
68
0
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Expression> as core::fmt::Debug>::fmt
Unexecuted instantiation: <naga::arena::Arena<naga::ir::LocalVariable> as core::fmt::Debug>::fmt
69
}
70
71
impl<T> Arena<T> {
72
    /// Create a new arena with no initial capacity allocated.
73
3.73M
    pub const fn new() -> Self {
74
3.73M
        Arena {
75
3.73M
            data: Vec::new(),
76
3.73M
            span_info: Vec::new(),
77
3.73M
        }
78
3.73M
    }
<naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode>>::new
Line
Count
Source
73
168
    pub const fn new() -> Self {
74
168
        Arena {
75
168
            data: Vec::new(),
76
168
            span_info: Vec::new(),
77
168
        }
78
168
    }
<naga::arena::Arena<naga::ir::Expression>>::new
Line
Count
Source
73
109
    pub const fn new() -> Self {
74
109
        Arena {
75
109
            data: Vec::new(),
76
109
            span_info: Vec::new(),
77
109
        }
78
109
    }
<naga::arena::Arena<naga::ir::LocalVariable>>::new
Line
Count
Source
73
2.83M
    pub const fn new() -> Self {
74
2.83M
        Arena {
75
2.83M
            data: Vec::new(),
76
2.83M
            span_info: Vec::new(),
77
2.83M
        }
78
2.83M
    }
<naga::arena::Arena<naga::ir::GlobalVariable>>::new
Line
Count
Source
73
63
    pub const fn new() -> Self {
74
63
        Arena {
75
63
            data: Vec::new(),
76
63
            span_info: Vec::new(),
77
63
        }
78
63
    }
<naga::arena::Arena<naga::ir::Constant>>::new
Line
Count
Source
73
63
    pub const fn new() -> Self {
74
63
        Arena {
75
63
            data: Vec::new(),
76
63
            span_info: Vec::new(),
77
63
        }
78
63
    }
<naga::arena::Arena<naga::ir::Function>>::new
Line
Count
Source
73
108
    pub const fn new() -> Self {
74
108
        Arena {
75
108
            data: Vec::new(),
76
108
            span_info: Vec::new(),
77
108
        }
78
108
    }
<naga::arena::Arena<naga::ir::Override>>::new
Line
Count
Source
73
63
    pub const fn new() -> Self {
74
63
        Arena {
75
63
            data: Vec::new(),
76
63
            span_info: Vec::new(),
77
63
        }
78
63
    }
Unexecuted instantiation: <naga::arena::Arena<naga::front::glsl::ast::HirExpr>>::new
<naga::arena::Arena<naga::front::wgsl::parse::ast::Expression>>::new
Line
Count
Source
73
105
    pub const fn new() -> Self {
74
105
        Arena {
75
105
            data: Vec::new(),
76
105
            span_info: Vec::new(),
77
105
        }
78
105
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::new
Line
Count
Source
73
105
    pub const fn new() -> Self {
74
105
        Arena {
75
105
            data: Vec::new(),
76
105
            span_info: Vec::new(),
77
105
        }
78
105
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Type>>::new
Line
Count
Source
73
105
    pub const fn new() -> Self {
74
105
        Arena {
75
105
            data: Vec::new(),
76
105
            span_info: Vec::new(),
77
105
        }
78
105
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Local>>::new
Line
Count
Source
73
904k
    pub const fn new() -> Self {
74
904k
        Arena {
75
904k
            data: Vec::new(),
76
904k
            span_info: Vec::new(),
77
904k
        }
78
904k
    }
79
80
    /// Extracts the inner vector.
81
    #[allow(clippy::missing_const_for_fn)] // ignore due to requirement of #![feature(const_precise_live_drops)]
82
0
    pub fn into_inner(self) -> Vec<T> {
83
0
        self.data
84
0
    }
85
86
    /// Returns the current number of items stored in this arena.
87
1.53M
    pub fn len(&self) -> usize {
88
1.53M
        self.data.len()
89
1.53M
    }
<naga::arena::Arena<naga::ir::Expression>>::len
Line
Count
Source
87
1.53M
    pub fn len(&self) -> usize {
88
1.53M
        self.data.len()
89
1.53M
    }
<naga::arena::Arena<naga::ir::GlobalVariable>>::len
Line
Count
Source
87
21
    pub fn len(&self) -> usize {
88
21
        self.data.len()
89
21
    }
<naga::arena::Arena<naga::ir::Constant>>::len
Line
Count
Source
87
21
    pub fn len(&self) -> usize {
88
21
        self.data.len()
89
21
    }
<naga::arena::Arena<naga::ir::Function>>::len
Line
Count
Source
87
76
    pub fn len(&self) -> usize {
88
76
        self.data.len()
89
76
    }
<naga::arena::Arena<naga::ir::Override>>::len
Line
Count
Source
87
21
    pub fn len(&self) -> usize {
88
21
        self.data.len()
89
21
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::len
Line
Count
Source
87
94
    pub fn len(&self) -> usize {
88
94
        self.data.len()
89
94
    }
90
91
    /// Returns `true` if the arena contains no elements.
92
0
    pub fn is_empty(&self) -> bool {
93
0
        self.data.is_empty()
94
0
    }
95
96
    /// Returns an iterator over the items stored in this arena, returning both
97
    /// the item's handle and a reference to it.
98
162k
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
162k
        self.data
100
162k
            .iter()
101
162k
            .enumerate()
102
4.76G
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
Unexecuted instantiation: <naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode>>::iter::{closure#0}
<naga::arena::Arena<naga::ir::Expression>>::iter::{closure#0}
Line
Count
Source
102
4.76G
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
<naga::arena::Arena<naga::ir::LocalVariable>>::iter::{closure#0}
Line
Count
Source
102
4.54k
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable>>::iter::{closure#0}
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Constant>>::iter::{closure#0}
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::iter::{closure#0}
<naga::arena::Arena<naga::ir::Override>>::iter::{closure#0}
Line
Count
Source
102
5
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::iter::{closure#0}
Line
Count
Source
102
29.1k
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
162k
    }
Unexecuted instantiation: <naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode>>::iter
<naga::arena::Arena<naga::ir::Expression>>::iter
Line
Count
Source
98
162k
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
162k
        self.data
100
162k
            .iter()
101
162k
            .enumerate()
102
162k
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
162k
    }
<naga::arena::Arena<naga::ir::LocalVariable>>::iter
Line
Count
Source
98
10
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
10
        self.data
100
10
            .iter()
101
10
            .enumerate()
102
10
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
10
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable>>::iter
<naga::arena::Arena<naga::ir::Constant>>::iter
Line
Count
Source
98
21
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
21
        self.data
100
21
            .iter()
101
21
            .enumerate()
102
21
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
21
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::iter
<naga::arena::Arena<naga::ir::Override>>::iter
Line
Count
Source
98
21
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
21
        self.data
100
21
            .iter()
101
21
            .enumerate()
102
21
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
21
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::iter
Line
Count
Source
98
94
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> + ExactSizeIterator {
99
94
        self.data
100
94
            .iter()
101
94
            .enumerate()
102
94
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
103
94
    }
104
105
    /// Returns an iterator over the items stored in this arena, returning both
106
    /// the item's handle and a reference to it.
107
0
    pub fn iter_mut_span(
108
0
        &mut self,
109
0
    ) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T, &Span)> + ExactSizeIterator {
110
0
        self.data
111
0
            .iter_mut()
112
0
            .zip(self.span_info.iter())
113
0
            .enumerate()
114
0
            .map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
115
0
    }
116
117
    /// Drains the arena, returning an iterator over the items stored.
118
0
    pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, T, Span)> {
119
0
        let arena = core::mem::take(self);
120
0
        arena
121
0
            .data
122
0
            .into_iter()
123
0
            .zip(arena.span_info)
124
0
            .enumerate()
125
0
            .map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
126
0
    }
127
128
    /// Returns a iterator over the items stored in this arena,
129
    /// returning both the item's handle and a mutable reference to it.
130
10
    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T)> {
131
10
        self.data
132
10
            .iter_mut()
133
10
            .enumerate()
134
4.54k
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Expression>>::iter_mut::{closure#0}
<naga::arena::Arena<naga::ir::LocalVariable>>::iter_mut::{closure#0}
Line
Count
Source
134
4.54k
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::iter_mut::{closure#0}
135
10
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Expression>>::iter_mut
<naga::arena::Arena<naga::ir::LocalVariable>>::iter_mut
Line
Count
Source
130
10
    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T)> {
131
10
        self.data
132
10
            .iter_mut()
133
10
            .enumerate()
134
10
            .map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
135
10
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::iter_mut
136
137
    /// Adds a new value to the arena, returning a typed handle.
138
17.7M
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
17.7M
        let index = self.data.len();
140
17.7M
        self.data.push(value);
141
17.7M
        self.span_info.push(span);
142
17.7M
        Handle::from_usize(index)
143
17.7M
    }
Unexecuted instantiation: <naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode>>::append
<naga::arena::Arena<naga::ir::Expression>>::append
Line
Count
Source
138
5.59M
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
5.59M
        let index = self.data.len();
140
5.59M
        self.data.push(value);
141
5.59M
        self.span_info.push(span);
142
5.59M
        Handle::from_usize(index)
143
5.59M
    }
<naga::arena::Arena<naga::ir::LocalVariable>>::append
Line
Count
Source
138
11.3k
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
11.3k
        let index = self.data.len();
140
11.3k
        self.data.push(value);
141
11.3k
        self.span_info.push(span);
142
11.3k
        Handle::from_usize(index)
143
11.3k
    }
<naga::arena::Arena<naga::ir::GlobalVariable>>::append
Line
Count
Source
138
2
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
2
        let index = self.data.len();
140
2
        self.data.push(value);
141
2
        self.span_info.push(span);
142
2
        Handle::from_usize(index)
143
2
    }
<naga::arena::Arena<naga::ir::Constant>>::append
Line
Count
Source
138
14
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
14
        let index = self.data.len();
140
14
        self.data.push(value);
141
14
        self.span_info.push(span);
142
14
        Handle::from_usize(index)
143
14
    }
<naga::arena::Arena<naga::ir::Function>>::append
Line
Count
Source
138
16
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
16
        let index = self.data.len();
140
16
        self.data.push(value);
141
16
        self.span_info.push(span);
142
16
        Handle::from_usize(index)
143
16
    }
<naga::arena::Arena<naga::ir::Override>>::append
Line
Count
Source
138
5
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
5
        let index = self.data.len();
140
5
        self.data.push(value);
141
5
        self.span_info.push(span);
142
5
        Handle::from_usize(index)
143
5
    }
Unexecuted instantiation: <naga::arena::Arena<naga::front::glsl::ast::HirExpr>>::append
<naga::arena::Arena<naga::front::wgsl::parse::ast::Expression>>::append
Line
Count
Source
138
11.2M
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
11.2M
        let index = self.data.len();
140
11.2M
        self.data.push(value);
141
11.2M
        self.span_info.push(span);
142
11.2M
        Handle::from_usize(index)
143
11.2M
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::append
Line
Count
Source
138
566k
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
566k
        let index = self.data.len();
140
566k
        self.data.push(value);
141
566k
        self.span_info.push(span);
142
566k
        Handle::from_usize(index)
143
566k
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Type>>::append
Line
Count
Source
138
273k
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
273k
        let index = self.data.len();
140
273k
        self.data.push(value);
141
273k
        self.span_info.push(span);
142
273k
        Handle::from_usize(index)
143
273k
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Local>>::append
Line
Count
Source
138
59.4k
    pub fn append(&mut self, value: T, span: Span) -> Handle<T> {
139
59.4k
        let index = self.data.len();
140
59.4k
        self.data.push(value);
141
59.4k
        self.span_info.push(span);
142
59.4k
        Handle::from_usize(index)
143
59.4k
    }
144
145
    /// Fetch a handle to an existing type.
146
0
    pub fn fetch_if<F: Fn(&T) -> bool>(&self, fun: F) -> Option<Handle<T>> {
147
0
        self.data
148
0
            .iter()
149
0
            .position(fun)
150
0
            .map(|index| unsafe { Handle::from_usize_unchecked(index) })
151
0
    }
152
153
    /// Adds a value with a custom check for uniqueness:
154
    /// returns a handle pointing to
155
    /// an existing element if the check succeeds, or adds a new
156
    /// element otherwise.
157
0
    pub fn fetch_if_or_append<F: Fn(&T, &T) -> bool>(
158
0
        &mut self,
159
0
        value: T,
160
0
        span: Span,
161
0
        fun: F,
162
0
    ) -> Handle<T> {
163
0
        if let Some(index) = self.data.iter().position(|d| fun(d, &value)) {
164
0
            unsafe { Handle::from_usize_unchecked(index) }
165
        } else {
166
0
            self.append(value, span)
167
        }
168
0
    }
169
170
    /// Adds a value with a check for uniqueness, where the check is plain comparison.
171
0
    pub fn fetch_or_append(&mut self, value: T, span: Span) -> Handle<T>
172
0
    where
173
0
        T: PartialEq,
174
    {
175
0
        self.fetch_if_or_append(value, span, T::eq)
176
0
    }
177
178
0
    pub fn try_get(&self, handle: Handle<T>) -> Result<&T, BadHandle> {
179
0
        self.data
180
0
            .get(handle.index())
181
0
            .ok_or_else(|| BadHandle::new(handle))
182
0
    }
183
184
    /// Get a mutable reference to an element in the arena.
185
0
    pub fn get_mut(&mut self, handle: Handle<T>) -> &mut T {
186
0
        self.data.get_mut(handle.index()).unwrap()
187
0
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable>>::get_mut
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::get_mut
188
189
    /// Get the range of handles from a particular number of elements to the end.
190
136k
    pub fn range_from(&self, old_length: usize) -> Range<T> {
191
136k
        let range = old_length as u32..self.data.len() as u32;
192
136k
        Range::from_index_range(range, self)
193
136k
    }
194
195
    /// Clears the arena keeping all allocations
196
0
    pub fn clear(&mut self) {
197
0
        self.data.clear()
198
0
    }
199
200
4.84M
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
4.84M
        *self
202
4.84M
            .span_info
203
4.84M
            .get(handle.index())
204
4.84M
            .unwrap_or(&Span::default())
205
4.84M
    }
<naga::arena::Arena<naga::ir::Expression>>::get_span
Line
Count
Source
200
1.84M
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
1.84M
        *self
202
1.84M
            .span_info
203
1.84M
            .get(handle.index())
204
1.84M
            .unwrap_or(&Span::default())
205
1.84M
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::LocalVariable>>::get_span
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable>>::get_span
<naga::arena::Arena<naga::ir::Constant>>::get_span
Line
Count
Source
200
13
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
13
        *self
202
13
            .span_info
203
13
            .get(handle.index())
204
13
            .unwrap_or(&Span::default())
205
13
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::get_span
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Override>>::get_span
<naga::arena::Arena<naga::front::wgsl::parse::ast::Expression>>::get_span
Line
Count
Source
200
2.99M
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
2.99M
        *self
202
2.99M
            .span_info
203
2.99M
            .get(handle.index())
204
2.99M
            .unwrap_or(&Span::default())
205
2.99M
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl>>::get_span
Line
Count
Source
200
6.41k
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
6.41k
        *self
202
6.41k
            .span_info
203
6.41k
            .get(handle.index())
204
6.41k
            .unwrap_or(&Span::default())
205
6.41k
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Local>>::get_span
Line
Count
Source
200
1
    pub fn get_span(&self, handle: Handle<T>) -> Span {
201
1
        *self
202
1
            .span_info
203
1
            .get(handle.index())
204
1
            .unwrap_or(&Span::default())
205
1
    }
206
207
    /// Assert that `handle` is valid for this arena.
208
0
    pub fn check_contains_handle(&self, handle: Handle<T>) -> Result<(), BadHandle> {
209
0
        if handle.index() < self.data.len() {
210
0
            Ok(())
211
        } else {
212
0
            Err(BadHandle::new(handle))
213
        }
214
0
    }
Unexecuted instantiation: <naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Expression>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::LocalVariable>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Constant>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function>>::check_contains_handle
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Override>>::check_contains_handle
215
216
    /// Assert that `range` is valid for this arena.
217
0
    pub fn check_contains_range(&self, range: &Range<T>) -> Result<(), BadRangeError> {
218
        // Since `range.inner` is a `Range<u32>`, we only need to check that the
219
        // start precedes the end, and that the end is in range.
220
0
        if range.inner.start > range.inner.end {
221
0
            return Err(BadRangeError::new(range.clone()));
222
0
        }
223
224
        // Empty ranges are tolerated: they can be produced by compaction.
225
0
        if range.inner.start == range.inner.end {
226
0
            return Ok(());
227
0
        }
228
229
0
        let last_handle = Handle::new(Index::new(range.inner.end - 1).unwrap());
230
0
        if self.check_contains_handle(last_handle).is_err() {
231
0
            return Err(BadRangeError::new(range.clone()));
232
0
        }
233
234
0
        Ok(())
235
0
    }
236
237
115
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
115
    where
239
115
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
115
        let mut index = 0;
242
115
        let mut retained = 0;
243
4.16M
        self.data.retain_mut(|elt| {
244
4.16M
            let handle = Handle::from_usize(index);
245
4.16M
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
4.16M
            if keep {
251
1.45M
                self.span_info[retained] = self.span_info[index];
252
1.45M
                retained += 1;
253
2.70M
            }
254
255
4.16M
            index += 1;
256
4.16M
            keep
257
4.16M
        });
<naga::arena::Arena<naga::ir::Expression>>::retain_mut::<<naga::compact::FunctionMap>::compact::{closure#0}>::{closure#0}
Line
Count
Source
243
464k
        self.data.retain_mut(|elt| {
244
464k
            let handle = Handle::from_usize(index);
245
464k
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
464k
            if keep {
251
275k
                self.span_info[retained] = self.span_info[index];
252
275k
                retained += 1;
253
275k
            }
254
255
464k
            index += 1;
256
464k
            keep
257
464k
        });
<naga::arena::Arena<naga::ir::Expression>>::retain_mut::<naga::compact::compact::{closure#1}>::{closure#0}
Line
Count
Source
243
3.69M
        self.data.retain_mut(|elt| {
244
3.69M
            let handle = Handle::from_usize(index);
245
3.69M
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
3.69M
            if keep {
251
1.18M
                self.span_info[retained] = self.span_info[index];
252
1.18M
                retained += 1;
253
2.51M
            }
254
255
3.69M
            index += 1;
256
3.69M
            keep
257
3.69M
        });
<naga::arena::Arena<naga::ir::GlobalVariable>>::retain_mut::<naga::compact::compact::{closure#4}>::{closure#0}
Line
Count
Source
243
1
        self.data.retain_mut(|elt| {
244
1
            let handle = Handle::from_usize(index);
245
1
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
1
            if keep {
251
1
                self.span_info[retained] = self.span_info[index];
252
1
                retained += 1;
253
1
            }
254
255
1
            index += 1;
256
1
            keep
257
1
        });
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Constant>>::retain_mut::<naga::compact::compact::{closure#2}>::{closure#0}
<naga::arena::Arena<naga::ir::Function>>::retain_mut::<naga::compact::compact::{closure#5}>::{closure#0}
Line
Count
Source
243
10
        self.data.retain_mut(|elt| {
244
10
            let handle = Handle::from_usize(index);
245
10
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
10
            if keep {
251
10
                self.span_info[retained] = self.span_info[index];
252
10
                retained += 1;
253
10
            }
254
255
10
            index += 1;
256
10
            keep
257
10
        });
<naga::arena::Arena<naga::ir::Override>>::retain_mut::<naga::compact::compact::{closure#3}>::{closure#0}
Line
Count
Source
243
5
        self.data.retain_mut(|elt| {
244
5
            let handle = Handle::from_usize(index);
245
5
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
5
            if keep {
251
5
                self.span_info[retained] = self.span_info[index];
252
5
                retained += 1;
253
5
            }
254
255
5
            index += 1;
256
5
            keep
257
5
        });
258
259
115
        self.span_info.truncate(retained);
260
115
    }
<naga::arena::Arena<naga::ir::Expression>>::retain_mut::<<naga::compact::FunctionMap>::compact::{closure#0}>
Line
Count
Source
237
10
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
10
    where
239
10
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
10
        let mut index = 0;
242
10
        let mut retained = 0;
243
10
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
10
        self.span_info.truncate(retained);
260
10
    }
<naga::arena::Arena<naga::ir::Expression>>::retain_mut::<naga::compact::compact::{closure#1}>
Line
Count
Source
237
21
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
21
    where
239
21
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
21
        let mut index = 0;
242
21
        let mut retained = 0;
243
21
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
21
        self.span_info.truncate(retained);
260
21
    }
<naga::arena::Arena<naga::ir::GlobalVariable>>::retain_mut::<naga::compact::compact::{closure#4}>
Line
Count
Source
237
21
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
21
    where
239
21
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
21
        let mut index = 0;
242
21
        let mut retained = 0;
243
21
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
21
        self.span_info.truncate(retained);
260
21
    }
<naga::arena::Arena<naga::ir::Constant>>::retain_mut::<naga::compact::compact::{closure#2}>
Line
Count
Source
237
21
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
21
    where
239
21
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
21
        let mut index = 0;
242
21
        let mut retained = 0;
243
21
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
21
        self.span_info.truncate(retained);
260
21
    }
<naga::arena::Arena<naga::ir::Function>>::retain_mut::<naga::compact::compact::{closure#5}>
Line
Count
Source
237
21
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
21
    where
239
21
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
21
        let mut index = 0;
242
21
        let mut retained = 0;
243
21
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
21
        self.span_info.truncate(retained);
260
21
    }
<naga::arena::Arena<naga::ir::Override>>::retain_mut::<naga::compact::compact::{closure#3}>
Line
Count
Source
237
21
    pub(crate) fn retain_mut<P>(&mut self, mut predicate: P)
238
21
    where
239
21
        P: FnMut(Handle<T>, &mut T) -> bool,
240
    {
241
21
        let mut index = 0;
242
21
        let mut retained = 0;
243
21
        self.data.retain_mut(|elt| {
244
            let handle = Handle::from_usize(index);
245
            let keep = predicate(handle, elt);
246
247
            // Since `predicate` needs mutable access to each element,
248
            // we can't feasibly call it twice, so we have to compact
249
            // spans by hand in parallel as part of this iteration.
250
            if keep {
251
                self.span_info[retained] = self.span_info[index];
252
                retained += 1;
253
            }
254
255
            index += 1;
256
            keep
257
        });
258
259
21
        self.span_info.truncate(retained);
260
21
    }
261
}
262
263
#[cfg(feature = "deserialize")]
264
impl<'de, T> serde::Deserialize<'de> for Arena<T>
265
where
266
    T: serde::Deserialize<'de>,
267
{
268
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
269
    where
270
        D: serde::Deserializer<'de>,
271
    {
272
        let data = Vec::deserialize(deserializer)?;
273
        let span_info = core::iter::repeat_n(Span::default(), data.len()).collect();
274
275
        Ok(Self { data, span_info })
276
    }
277
}
278
279
impl<T> ops::Index<Handle<T>> for Arena<T> {
280
    type Output = T;
281
16.8M
    fn index(&self, handle: Handle<T>) -> &T {
282
16.8M
        &self.data[handle.index()]
283
16.8M
    }
Unexecuted instantiation: <naga::arena::Arena<naga::diagnostic_filter::DiagnosticFilterNode> as core::ops::index::Index<naga::arena::handle::Handle<naga::diagnostic_filter::DiagnosticFilterNode>>>::index
<naga::arena::Arena<naga::ir::Expression> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::Expression>>>::index
Line
Count
Source
281
15.0M
    fn index(&self, handle: Handle<T>) -> &T {
282
15.0M
        &self.data[handle.index()]
283
15.0M
    }
<naga::arena::Arena<naga::ir::LocalVariable> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::LocalVariable>>>::index
Line
Count
Source
281
11.2k
    fn index(&self, handle: Handle<T>) -> &T {
282
11.2k
        &self.data[handle.index()]
283
11.2k
    }
<naga::arena::Arena<naga::ir::GlobalVariable> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::GlobalVariable>>>::index
Line
Count
Source
281
2
    fn index(&self, handle: Handle<T>) -> &T {
282
2
        &self.data[handle.index()]
283
2
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Constant> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::Constant>>>::index
<naga::arena::Arena<naga::ir::Function> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::Function>>>::index
Line
Count
Source
281
10
    fn index(&self, handle: Handle<T>) -> &T {
282
10
        &self.data[handle.index()]
283
10
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Override> as core::ops::index::Index<naga::arena::handle::Handle<naga::ir::Override>>>::index
Unexecuted instantiation: <naga::arena::Arena<naga::front::glsl::ast::HirExpr> as core::ops::index::Index<naga::arena::handle::Handle<naga::front::glsl::ast::HirExpr>>>::index
<naga::arena::Arena<naga::front::wgsl::parse::ast::Expression> as core::ops::index::Index<naga::arena::handle::Handle<naga::front::wgsl::parse::ast::Expression>>>::index
Line
Count
Source
281
1.73M
    fn index(&self, handle: Handle<T>) -> &T {
282
1.73M
        &self.data[handle.index()]
283
1.73M
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::GlobalDecl> as core::ops::index::Index<naga::arena::handle::Handle<naga::front::wgsl::parse::ast::GlobalDecl>>>::index
Line
Count
Source
281
20.9k
    fn index(&self, handle: Handle<T>) -> &T {
282
20.9k
        &self.data[handle.index()]
283
20.9k
    }
<naga::arena::Arena<naga::front::wgsl::parse::ast::Type> as core::ops::index::Index<naga::arena::handle::Handle<naga::front::wgsl::parse::ast::Type>>>::index
Line
Count
Source
281
29.2k
    fn index(&self, handle: Handle<T>) -> &T {
282
29.2k
        &self.data[handle.index()]
283
29.2k
    }
284
}
285
286
impl<T> ops::IndexMut<Handle<T>> for Arena<T> {
287
0
    fn index_mut(&mut self, handle: Handle<T>) -> &mut T {
288
0
        &mut self.data[handle.index()]
289
0
    }
Unexecuted instantiation: <naga::arena::Arena<naga::ir::GlobalVariable> as core::ops::index::IndexMut<naga::arena::handle::Handle<naga::ir::GlobalVariable>>>::index_mut
Unexecuted instantiation: <naga::arena::Arena<naga::ir::Function> as core::ops::index::IndexMut<naga::arena::handle::Handle<naga::ir::Function>>>::index_mut
290
}
291
292
impl<T> ops::Index<Range<T>> for Arena<T> {
293
    type Output = [T];
294
0
    fn index(&self, range: Range<T>) -> &[T] {
295
0
        &self.data[range.inner.start as usize..range.inner.end as usize]
296
0
    }
297
}
298
299
#[cfg(test)]
300
mod tests {
301
    use super::*;
302
303
    #[test]
304
    fn append_non_unique() {
305
        let mut arena: Arena<u8> = Arena::new();
306
        let t1 = arena.append(0, Default::default());
307
        let t2 = arena.append(0, Default::default());
308
        assert!(t1 != t2);
309
        assert!(arena[t1] == arena[t2]);
310
    }
311
312
    #[test]
313
    fn append_unique() {
314
        let mut arena: Arena<u8> = Arena::new();
315
        let t1 = arena.append(0, Default::default());
316
        let t2 = arena.append(1, Default::default());
317
        assert!(t1 != t2);
318
        assert!(arena[t1] != arena[t2]);
319
    }
320
321
    #[test]
322
    fn fetch_or_append_non_unique() {
323
        let mut arena: Arena<u8> = Arena::new();
324
        let t1 = arena.fetch_or_append(0, Default::default());
325
        let t2 = arena.fetch_or_append(0, Default::default());
326
        assert!(t1 == t2);
327
        assert!(arena[t1] == arena[t2])
328
    }
329
330
    #[test]
331
    fn fetch_or_append_unique() {
332
        let mut arena: Arena<u8> = Arena::new();
333
        let t1 = arena.fetch_or_append(0, Default::default());
334
        let t2 = arena.fetch_or_append(1, Default::default());
335
        assert!(t1 != t2);
336
        assert!(arena[t1] != arena[t2]);
337
    }
338
}