Skip to content

Commit 8f76248

Browse files
authored
Remove impl<T: AsRef<[u8]>> From<T> for Buffer that easily accidentally copies data (#6043)
* deprecate auto copy, ask explicit reference * update comments * make cargo doc happy
1 parent 741bbf6 commit 8f76248

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

arrow-buffer/src/buffer/immutable.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -356,16 +356,29 @@ impl Buffer {
356356
}
357357
}
358358

359-
/// Creating a `Buffer` instance by copying the memory from a `AsRef<[u8]>` into a newly
360-
/// allocated memory region.
361-
impl<T: AsRef<[u8]>> From<T> for Buffer {
362-
fn from(p: T) -> Self {
363-
// allocate aligned memory buffer
364-
let slice = p.as_ref();
365-
let len = slice.len();
366-
let mut buffer = MutableBuffer::new(len);
367-
buffer.extend_from_slice(slice);
368-
buffer.into()
359+
/// Note that here we deliberately do not implement
360+
/// `impl<T: AsRef<[u8]>> From<T> for Buffer`
361+
/// As it would accept `Buffer::from(vec![...])` that would cause an unexpected copy.
362+
/// Instead, we ask user to be explicit when copying is occurring, e.g., `Buffer::from(vec![...].to_byte_slice())`.
363+
/// For zero-copy conversion, user should use `Buffer::from_vec(vec![...])`.
364+
///
365+
/// Since we removed impl for `AsRef<u8>`, we added the following three specific implementations to reduce API breakage.
366+
/// See <https://github.com/apache/arrow-rs/issues/6033> for more discussion on this.
367+
impl From<&[u8]> for Buffer {
368+
fn from(p: &[u8]) -> Self {
369+
Self::from_slice_ref(p)
370+
}
371+
}
372+
373+
impl<const N: usize> From<[u8; N]> for Buffer {
374+
fn from(p: [u8; N]) -> Self {
375+
Self::from_slice_ref(p)
376+
}
377+
}
378+
379+
impl<const N: usize> From<&[u8; N]> for Buffer {
380+
fn from(p: &[u8; N]) -> Self {
381+
Self::from_slice_ref(p)
369382
}
370383
}
371384

0 commit comments

Comments
 (0)