This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch 57_maintenance
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/57_maintenance by this push:
     new 74cf9142cc [57_maintenance] Mark `BufferBuilder::new_from_buffer` as 
unsafe (#9292) (#9312)
74cf9142cc is described below

commit 74cf9142cc36dac1514cd0bcc71ed6974155689e
Author: Andrew Lamb <[email protected]>
AuthorDate: Mon Feb 2 10:05:15 2026 -0500

    [57_maintenance] Mark `BufferBuilder::new_from_buffer` as unsafe (#9292) 
(#9312)
    
    - Part of https://github.com/apache/arrow-rs/issues/9240
    - Related to https://github.com/apache/arrow-rs/issues/9287
    
    This is a backport of the following PR to the 57 line
    - https://github.com/apache/arrow-rs/pull/9292 from @Jefffrey
    
    Note this is technically an API change (if this API is used by
    downstream crates they will have to mark the callsites with `unsafe`).
    However per a conversation with @Jefffrey
    https://github.com/apache/arrow-rs/pull/9292#issuecomment-3823306113 and
    our general focus on safety, it seems better to err on the safety side
    
    > I think breaking changes are fine if its for the sake of fixing
    unsound behaviour 🤔
    
    Co-authored-by: Jeffrey Vo <[email protected]>
---
 arrow-buffer/src/builder/mod.rs | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/arrow-buffer/src/builder/mod.rs b/arrow-buffer/src/builder/mod.rs
index d809b0939f..e44397258f 100644
--- a/arrow-buffer/src/builder/mod.rs
+++ b/arrow-buffer/src/builder/mod.rs
@@ -70,7 +70,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     ///
     /// assert!(builder.capacity() >= 10);
@@ -87,7 +86,11 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     }
 
     /// Creates a new builder from a [`MutableBuffer`]
-    pub fn new_from_buffer(buffer: MutableBuffer) -> Self {
+    ///
+    /// # Safety
+    ///
+    /// - `buffer` bytes must be aligned to type `T`
+    pub unsafe fn new_from_buffer(buffer: MutableBuffer) -> Self {
         let buffer_len = buffer.len();
         Self {
             buffer,
@@ -102,7 +105,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.append(42);
     ///
@@ -118,7 +120,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.append(42);
     ///
@@ -149,7 +150,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.advance(2);
     ///
@@ -167,7 +167,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.reserve(10);
     ///
@@ -185,7 +184,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.append(42);
     ///
@@ -205,7 +203,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.append_n(10, 42);
     ///
@@ -223,12 +220,12 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u32>::new(10);
     /// builder.append_n_zeroed(3);
     ///
     /// assert_eq!(builder.len(), 3);
     /// assert_eq!(builder.as_slice(), &[0, 0, 0])
+    /// ```
     #[inline]
     pub fn append_n_zeroed(&mut self, n: usize) {
         self.buffer.extend_zeros(n * std::mem::size_of::<T>());
@@ -241,7 +238,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u8>::new(10);
     /// builder.append_slice(&[42, 44, 46]);
     ///
@@ -257,7 +253,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<f64>::new(10);
     /// builder.append(1.3);
     /// builder.append_n(2, 2.3);
@@ -280,7 +275,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<f32>::new(10);
     ///
     /// builder.append_slice(&[1., 2., 3.4]);
@@ -307,7 +301,6 @@ impl<T: ArrowNativeType> BufferBuilder<T> {
     ///
     /// ```
     /// # use arrow_buffer::builder::BufferBuilder;
-    ///
     /// let mut builder = BufferBuilder::<u16>::new(10);
     ///
     /// builder.append_slice(&[42, 44, 46]);
@@ -377,7 +370,10 @@ impl<T: ArrowNativeType> Extend<T> for BufferBuilder<T> {
 
 impl<T: ArrowNativeType> From<Vec<T>> for BufferBuilder<T> {
     fn from(value: Vec<T>) -> Self {
-        Self::new_from_buffer(MutableBuffer::from(value))
+        let buffer = MutableBuffer::from(value);
+        // SAFETY
+        // - buffer is aligned to T
+        unsafe { Self::new_from_buffer(buffer) }
     }
 }
 

Reply via email to