about summary refs log tree commit diff
path: root/library/proc_macro/src/bridge/buffer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/proc_macro/src/bridge/buffer.rs')
-rw-r--r--library/proc_macro/src/bridge/buffer.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs
index a2030b9b8bf..717201aef10 100644
--- a/library/proc_macro/src/bridge/buffer.rs
+++ b/library/proc_macro/src/bridge/buffer.rs
@@ -78,8 +78,23 @@ impl<T: Copy> Buffer<T> {
         mem::take(self)
     }
 
+    // We have the array method separate from extending from a slice. This is
+    // because in the case of small arrays, codegen can be more efficient
+    // (avoiding a memmove call). With extend_from_slice, LLVM at least
+    // currently is not able to make that optimization.
+    pub(super) fn extend_from_array<const N: usize>(&mut self, xs: &[T; N]) {
+        if xs.len() > (self.capacity - self.len) {
+            let b = self.take();
+            *self = (b.reserve)(b, xs.len());
+        }
+        unsafe {
+            xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
+            self.len += xs.len();
+        }
+    }
+
     pub(super) fn extend_from_slice(&mut self, xs: &[T]) {
-        if xs.len() > self.capacity.wrapping_sub(self.len) {
+        if xs.len() > (self.capacity - self.len) {
             let b = self.take();
             *self = (b.reserve)(b, xs.len());
         }