@@ -125,6 +125,11 @@ impl<I, T> IterExt<T> for I
125125where
126126 I : IntoIterator < Item = T > ,
127127{
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.
128133 #[ inline]
129134 default fn alloc_from_iter ( self , arena : & TypedArena < T > ) -> & mut [ T ] {
130135 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> {
139144 if len == 0 {
140145 return & mut [ ] ;
141146 }
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.
143148 unsafe {
144149 let start_ptr = arena. alloc_raw_slice ( len) ;
145150 self . as_slice ( ) . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -156,7 +161,7 @@ impl<T> IterExt<T> for Vec<T> {
156161 if len == 0 {
157162 return & mut [ ] ;
158163 }
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.
160165 unsafe {
161166 let start_ptr = arena. alloc_raw_slice ( len) ;
162167 self . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -173,7 +178,7 @@ impl<A: smallvec::Array> IterExt<A::Item> for SmallVec<A> {
173178 if len == 0 {
174179 return & mut [ ] ;
175180 }
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.
177182 unsafe {
178183 let start_ptr = arena. alloc_raw_slice ( len) ;
179184 self . as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
@@ -520,10 +525,19 @@ impl DroplessArena {
520525 }
521526}
522527
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+ ///
527541#[ rustc_macro_transparency = "semitransparent" ]
528542pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] ) {
529543 #[ derive( Default ) ]
0 commit comments