@@ -125,6 +125,11 @@ impl<I, T> IterExt<T> for I
125
125
where
126
126
I : IntoIterator < Item = T > ,
127
127
{
128
+ // This default collects into a `SmallVec` and then allocates by copying
129
+ // from it. The specializations below for types like `Vec` are more
130
+ // efficient, copying directly without the intermediate collecting step.
131
+ // This default could be made more efficient, like
132
+ // `DroplessArena::alloc_from_iter`, but it's not hot enough to bother.
128
133
#[ inline]
129
134
default fn alloc_from_iter ( self , arena : & TypedArena < T > ) -> & mut [ T ] {
130
135
let vec: SmallVec < [ _ ; 8 ] > = self . into_iter ( ) . collect ( ) ;
@@ -139,7 +144,7 @@ impl<T, const N: usize> IterExt<T> for std::array::IntoIter<T, N> {
139
144
if len == 0 {
140
145
return & mut [ ] ;
141
146
}
142
- // Move the content to the arena by copying and then forgetting it
147
+ // Move the content to the arena by copying and then forgetting it.
143
148
unsafe {
144
149
let start_ptr = arena. alloc_raw_slice ( len) ;
145
150
self . as_slice ( ) . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -156,7 +161,7 @@ impl<T> IterExt<T> for Vec<T> {
156
161
if len == 0 {
157
162
return & mut [ ] ;
158
163
}
159
- // Move the content to the arena by copying and then forgetting it
164
+ // Move the content to the arena by copying and then forgetting it.
160
165
unsafe {
161
166
let start_ptr = arena. alloc_raw_slice ( len) ;
162
167
self . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -173,7 +178,7 @@ impl<A: smallvec::Array> IterExt<A::Item> for SmallVec<A> {
173
178
if len == 0 {
174
179
return & mut [ ] ;
175
180
}
176
- // Move the content to the arena by copying and then forgetting it
181
+ // Move the content to the arena by copying and then forgetting it.
177
182
unsafe {
178
183
let start_ptr = arena. alloc_raw_slice ( len) ;
179
184
self . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -520,10 +525,19 @@ impl DroplessArena {
520
525
}
521
526
}
522
527
523
- // Declare an `Arena` containing one dropless arena and many typed arenas (the
524
- // types of the typed arenas are specified by the arguments). The dropless
525
- // arena will be used for any types that impl `Copy`, and also for any of the
526
- // specified types that satisfy `!mem::needs_drop`.
528
+ /// Declare an `Arena` containing one dropless arena and many typed arenas (the
529
+ /// types of the typed arenas are specified by the arguments).
530
+ ///
531
+ /// There are three cases of interest.
532
+ /// - Types that are `Copy`: these need not be specified in the arguments. They
533
+ /// will use the `DroplessArena`.
534
+ /// - Types that are `!Copy` and `!Drop`: these must be specified in the
535
+ /// arguments. An empty `TypedArena` will be created for each one, but the
536
+ /// `DroplessArena` will always be used and the `TypedArena` will stay empty.
537
+ /// This is odd but harmless, because an empty arena allocates no memory.
538
+ /// - Types that are `!Copy` and `Drop`: these must be specified in the
539
+ /// arguments. The `TypedArena` will be used for them.
540
+ ///
527
541
#[ rustc_macro_transparency = "semitransparent" ]
528
542
pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] ) {
529
543
#[ derive( Default ) ]
0 commit comments