Skip to content

Commit e261cb8

Browse files
authored
Merge pull request #190 from adamreichold/slice-box-safety
Avoid raw pointers in SliceBox and make the Send bound explicit
2 parents 409a940 + 537a0e6 commit e261cb8

File tree

3 files changed

+17
-18
lines changed

3 files changed

+17
-18
lines changed

src/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
422422
{
423423
let dims = dims.into_dimension();
424424
let container = SliceBox::new(slice);
425-
let data_ptr = container.data;
425+
let data_ptr = container.data.as_ptr();
426426
let cell = pyo3::PyClassInitializer::from(container)
427427
.create_cell(py)
428428
.expect("Object creation failed.");

src/dtype.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl DataType {
166166
}
167167

168168
/// Represents that a type can be an element of `PyArray`.
169-
pub trait Element: Clone {
169+
pub trait Element: Clone + Send {
170170
/// `DataType` corresponding to this type.
171171
const DATA_TYPE: DataType;
172172

src/slice_box.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,39 @@ use pyo3::pyclass_slots::PyClassDummySlot;
44
use pyo3::{ffi, type_object, types::PyAny, PyCell};
55

66
pub(crate) struct SliceBox<T> {
7-
pub(crate) data: *mut [T],
7+
pub(crate) data: Box<[T]>,
88
}
99

1010
impl<T> SliceBox<T> {
11-
pub(crate) fn new(value: Box<[T]>) -> Self {
12-
SliceBox {
13-
data: Box::into_raw(value),
14-
}
11+
pub(crate) fn new(data: Box<[T]>) -> Self {
12+
Self { data }
1513
}
1614
}
1715

18-
impl<T> Drop for SliceBox<T> {
19-
fn drop(&mut self) {
20-
let _boxed_slice = unsafe { Box::from_raw(self.data) };
21-
}
22-
}
23-
24-
impl<T> PyClass for SliceBox<T> {
16+
impl<T> PyClass for SliceBox<T>
17+
where
18+
T: Send,
19+
{
2520
type Dict = PyClassDummySlot;
2621
type WeakRef = PyClassDummySlot;
2722
type BaseNativeType = PyAny;
2823
}
2924

30-
impl<T> PyClassImpl for SliceBox<T> {
25+
impl<T> PyClassImpl for SliceBox<T>
26+
where
27+
T: Send,
28+
{
3129
const DOC: &'static str = "Memory store for PyArray using rust's Box<[T]> \0";
3230

3331
type BaseType = PyAny;
3432
type Layout = PyCell<Self>;
3533
type ThreadChecker = ThreadCheckerStub<Self>;
3634
}
3735

38-
unsafe impl<T> type_object::PyTypeInfo for SliceBox<T> {
36+
unsafe impl<T> type_object::PyTypeInfo for SliceBox<T>
37+
where
38+
T: Send,
39+
{
3940
type AsRefTarget = PyCell<Self>;
4041
const NAME: &'static str = "SliceBox";
4142
const MODULE: Option<&'static str> = Some("_rust_numpy");
@@ -47,5 +48,3 @@ unsafe impl<T> type_object::PyTypeInfo for SliceBox<T> {
4748
TYPE_OBJECT.get_or_init::<Self>(py)
4849
}
4950
}
50-
51-
unsafe impl<T> Send for SliceBox<T> {}

0 commit comments

Comments
 (0)