/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 | | } |