Skip to content

Commit 526fb1f

Browse files
Remove unsafe_op_in_unsafe_fn from vortex-ffi (#3243)
We should remove this lint ignore as per https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html
1 parent 48a38a8 commit 526fb1f

File tree

6 files changed

+64
-56
lines changed

6 files changed

+64
-56
lines changed

vortex-ffi/src/array.rs

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ pub struct vx_array {
2525
/// Get the length of the array.
2626
#[unsafe(no_mangle)]
2727
pub unsafe extern "C-unwind" fn vx_array_len(array: *const vx_array) -> u64 {
28-
array.as_ref().vortex_expect("array null").inner.len() as u64
28+
unsafe { array.as_ref() }
29+
.vortex_expect("array null")
30+
.inner
31+
.len() as u64
2932
}
3033

3134
/// Get a pointer to the data type for an array.
@@ -34,7 +37,10 @@ pub unsafe extern "C-unwind" fn vx_array_len(array: *const vx_array) -> u64 {
3437
/// for ensuring that it is never dereferenced after the array has been freed.
3538
#[unsafe(no_mangle)]
3639
pub unsafe extern "C-unwind" fn vx_array_dtype(array: *const vx_array) -> *const DType {
37-
array.as_ref().vortex_expect("array null").inner.dtype()
40+
unsafe { array.as_ref() }
41+
.vortex_expect("array null")
42+
.inner
43+
.dtype()
3844
}
3945

4046
#[unsafe(no_mangle)]
@@ -44,7 +50,7 @@ pub unsafe extern "C-unwind" fn vx_array_get_field(
4450
error: *mut *mut vx_error,
4551
) -> *const vx_array {
4652
try_or(error, ptr::null(), || {
47-
let array = array.as_ref().vortex_expect("array null");
53+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
4854

4955
let field_array = array
5056
.inner
@@ -75,7 +81,7 @@ pub unsafe extern "C-unwind" fn vx_array_slice(
7581
stop: u32,
7682
error: *mut *mut vx_error,
7783
) -> *const vx_array {
78-
let array = array.as_ref().vortex_expect("array null");
84+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
7985
try_or(error, ptr::null_mut(), || {
8086
let sliced = array.inner.as_ref().slice(start as usize, stop as usize)?;
8187
Ok(Box::into_raw(Box::new(vx_array { inner: sliced })))
@@ -88,7 +94,7 @@ pub unsafe extern "C-unwind" fn vx_array_is_null(
8894
index: u32,
8995
error: *mut *mut vx_error,
9096
) -> bool {
91-
let array = array.as_ref().vortex_expect("array null");
97+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
9298
try_or(error, false, || array.inner.is_invalid(index as usize))
9399
}
94100

@@ -97,7 +103,7 @@ pub unsafe extern "C-unwind" fn vx_array_null_count(
97103
array: *const vx_array,
98104
error: *mut *mut vx_error,
99105
) -> u32 {
100-
let array = array.as_ref().vortex_expect("array null");
106+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
101107
try_or(error, 0, || {
102108
Ok(array.inner.as_ref().invalid_count()?.try_into()?)
103109
})
@@ -108,7 +114,7 @@ macro_rules! ffiarray_get_ptype {
108114
paste::paste! {
109115
#[unsafe(no_mangle)]
110116
pub unsafe extern "C-unwind" fn [<vx_array_get_ $ptype>](array: *const vx_array, index: u32) -> $ptype {
111-
let array = array.as_ref().vortex_expect("array null");
117+
let array = unsafe { array.as_ref() } .vortex_expect("array null");
112118
let value = array.inner.scalar_at(index as usize).vortex_expect("scalar_at");
113119
value.as_primitive()
114120
.as_::<$ptype>()
@@ -118,7 +124,7 @@ macro_rules! ffiarray_get_ptype {
118124

119125
#[unsafe(no_mangle)]
120126
pub unsafe extern "C-unwind" fn [<vx_array_get_storage_ $ptype>](array: *const vx_array, index: u32) -> $ptype {
121-
let array = array.as_ref().vortex_expect("array null");
127+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
122128
let value = array.inner.scalar_at(index as usize).vortex_expect("scalar_at");
123129
value.as_extension()
124130
.storage()
@@ -152,7 +158,7 @@ pub unsafe extern "C-unwind" fn vx_array_get_utf8(
152158
dst: *mut c_void,
153159
len: *mut c_int,
154160
) {
155-
let array = array.as_ref().vortex_expect("array null");
161+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
156162
let value = array
157163
.inner
158164
.as_ref()
@@ -161,9 +167,9 @@ pub unsafe extern "C-unwind" fn vx_array_get_utf8(
161167
let utf8_scalar = value.as_utf8();
162168
if let Some(buffer) = utf8_scalar.value() {
163169
let bytes = buffer.as_bytes();
164-
let dst = std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len());
170+
let dst = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
165171
dst.copy_from_slice(bytes);
166-
*len = bytes.len().try_into().vortex_unwrap();
172+
unsafe { *len = bytes.len().try_into().vortex_unwrap() };
167173
}
168174
}
169175

@@ -176,16 +182,16 @@ pub unsafe extern "C-unwind" fn vx_array_get_binary(
176182
dst: *mut c_void,
177183
len: *mut c_int,
178184
) {
179-
let array = array.as_ref().vortex_expect("array null");
185+
let array = unsafe { array.as_ref() }.vortex_expect("array null");
180186
let value = array
181187
.inner
182188
.scalar_at(index as usize)
183189
.vortex_expect("scalar_at");
184190
let utf8_scalar = value.as_binary();
185191
if let Some(bytes) = utf8_scalar.value() {
186-
let dst = std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len());
192+
let dst = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
187193
dst.copy_from_slice(&bytes);
188-
*len = bytes.len().try_into().vortex_unwrap();
194+
unsafe { *len = bytes.len().try_into().vortex_unwrap() };
189195
}
190196
}
191197

@@ -203,20 +209,20 @@ mod tests {
203209
fn test_simple() {
204210
unsafe {
205211
let primitive = PrimitiveArray::new(buffer![1i32, 2i32, 3i32], Validity::NonNullable);
206-
let ffi_array = Box::new(vx_array {
212+
let vx_array = Box::new(vx_array {
207213
inner: primitive.to_array(),
208214
});
209215

210-
assert_eq!(vx_array_len(&*ffi_array), 3);
216+
assert_eq!(vx_array_len(&*vx_array), 3);
211217

212-
let array_dtype = vx_array_dtype(&*ffi_array);
218+
let array_dtype = vx_array_dtype(&*vx_array);
213219
assert_eq!(vx_dtype_get(array_dtype), DTYPE_PRIMITIVE_I32);
214220

215-
assert_eq!(vx_array_get_i32(&*ffi_array, 0), 1);
216-
assert_eq!(vx_array_get_i32(&*ffi_array, 1), 2);
217-
assert_eq!(vx_array_get_i32(&*ffi_array, 2), 3);
221+
assert_eq!(vx_array_get_i32(&*vx_array, 0), 1);
222+
assert_eq!(vx_array_get_i32(&*vx_array, 1), 2);
223+
assert_eq!(vx_array_get_i32(&*vx_array, 2), 3);
218224

219-
vx_array_free(Box::into_raw(ffi_array));
225+
vx_array_free(Box::into_raw(vx_array));
220226
}
221227
}
222228
}

vortex-ffi/src/dtype.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// TODO(joe): remove me
2+
#![allow(clippy::panic)]
3+
14
use std::ffi::{CStr, c_char, c_int, c_void};
25
use std::ptr;
36
use std::sync::Arc;
@@ -51,10 +54,8 @@ pub unsafe extern "C-unwind" fn vx_dtype_new_list(
5154
element: *mut DType,
5255
nullable: bool,
5356
) -> *mut DType {
54-
assert!(!element.is_null(), "DType_new_list: null ptr");
55-
56-
let element_type = *Box::from_raw(element);
57-
let element_dtype = Arc::new(element_type);
57+
let element_type = unsafe { element.as_ref() }.vortex_expect("null dtype");
58+
let element_dtype = Arc::new(element_type.clone());
5859
let list_dtype = DType::List(element_dtype, nullable.into());
5960

6061
Box::into_raw(Box::new(list_dtype))
@@ -72,13 +73,15 @@ pub unsafe extern "C-unwind" fn vx_dtype_new_struct(
7273
let mut field_dtypes = Vec::with_capacity(len as usize);
7374

7475
for i in 0..len {
75-
let name_ptr = *names.add(i as usize);
76-
let name: Arc<str> = CStr::from_ptr(name_ptr).to_string_lossy().into();
77-
let dtype = Box::from_raw(*dtypes.add(i as usize));
78-
let dtype = *dtype;
76+
unsafe {
77+
let name_ptr = *names.add(i as usize);
78+
let name: Arc<str> = CStr::from_ptr(name_ptr).to_string_lossy().into();
79+
let dtype = Box::from_raw(*dtypes.add(i as usize));
80+
let dtype = *dtype;
7981

80-
rust_names.push(name);
81-
field_dtypes.push(dtype);
82+
rust_names.push(name);
83+
field_dtypes.push(dtype);
84+
}
8285
}
8386

8487
let field_names = FieldNames::from(rust_names);
@@ -90,13 +93,13 @@ pub unsafe extern "C-unwind" fn vx_dtype_new_struct(
9093
/// Free an [`DType`] and all associated resources.
9194
#[unsafe(no_mangle)]
9295
pub unsafe extern "C-unwind" fn vx_dtype_free(dtype: *mut DType) {
93-
drop(Box::from_raw(dtype));
96+
drop(unsafe { Box::from_raw(dtype) });
9497
}
9598

9699
/// Get the dtype variant tag for an [`DType`].
97100
#[unsafe(no_mangle)]
98101
pub unsafe extern "C-unwind" fn vx_dtype_get(dtype: *const DType) -> u8 {
99-
match dtype.as_ref().vortex_expect("null dtype") {
102+
match unsafe { dtype.as_ref() }.vortex_expect("null dtype") {
100103
DType::Null => DTYPE_NULL,
101104
DType::Bool(_) => DTYPE_BOOL,
102105
DType::Primitive(ptype, _) => match ptype {
@@ -159,10 +162,10 @@ pub unsafe extern "C-unwind" fn vx_dtype_field_name(
159162
let field_name = struct_dtype.names()[index as usize].as_ref();
160163
let bytes = field_name.as_bytes();
161164

162-
let dst_slice = std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len());
165+
let dst_slice = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
163166
dst_slice.copy_from_slice(bytes);
164167

165-
*len = bytes.len().try_into().vortex_unwrap();
168+
unsafe { *len = bytes.len().try_into().vortex_unwrap() };
166169
}
167170

168171
/// Get the dtype of a field in a `DTYPE_STRUCT` variant DType.
@@ -268,12 +271,12 @@ pub unsafe extern "C-unwind" fn vx_dtype_time_zone(
268271
TemporalMetadata::Timestamp(_, zone) => {
269272
if let Some(zone) = zone {
270273
let bytes = zone.as_bytes();
271-
let dst = std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len());
274+
let dst = unsafe { std::slice::from_raw_parts_mut(dst as *mut u8, bytes.len()) };
272275
dst.copy_from_slice(bytes);
273-
*len = bytes.len().try_into().vortex_unwrap();
276+
unsafe { *len = bytes.len().try_into().vortex_unwrap() };
274277
} else {
275278
// No time zone, using local timestamps.
276-
*len = 0;
279+
unsafe { *len = 0 };
277280
}
278281
}
279282
_ => panic!("DType_time_zone: not a timestamp metadata: {:?}", ext_dtype),

vortex-ffi/src/duckdb/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ pub unsafe extern "C-unwind" fn vx_duckdb_logical_type_to_dtype(
4545
) -> *mut DType {
4646
try_or(error, ptr::null_mut(), || {
4747
let field_names: Vec<Arc<str>> = (0..column_count)
48-
.map(|idx| to_string(*column_names.offset(idx as isize)))
48+
.map(|idx| unsafe { to_string(*column_names.offset(idx as isize)) })
4949
.map(Arc::from)
5050
.collect();
5151

5252
let types = (0..column_count)
53-
.map(|idx| {
53+
.map(|idx| unsafe {
5454
(
55-
LogicalTypeHandle::new_unowned(unsafe { *column_types.offset(idx as isize) }),
55+
LogicalTypeHandle::new_unowned(*column_types.offset(idx as isize)),
5656
*column_nullable.offset(idx as isize) != 0,
5757
)
5858
})
@@ -130,7 +130,7 @@ pub unsafe extern "C-unwind" fn vx_duckdb_chunk_to_array(
130130
.collect_vec();
131131

132132
let array = ArrayRef::from_duckdb(&NamedDataChunk {
133-
chunk: &DataChunkHandle::new_unowned(chunk),
133+
chunk: &unsafe { DataChunkHandle::new_unowned(chunk) },
134134
nullable: Some(&nullable),
135135
names: Some(struct_type.names().clone()),
136136
})?;

vortex-ffi/src/file.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ pub unsafe extern "C-unwind" fn vx_file_open_reader(
7777
if options.uri.is_null() {
7878
vortex_bail!("null uri")
7979
}
80-
let uri = CStr::from_ptr(options.uri).to_string_lossy();
80+
let uri = unsafe { CStr::from_ptr(options.uri) }.to_string_lossy();
8181
let uri: Url = uri.parse().vortex_expect("File_open: parse uri");
8282

83-
let prop_keys = to_string_vec(options.property_keys, options.property_len);
84-
let prop_vals = to_string_vec(options.property_vals, options.property_len);
83+
let prop_keys = unsafe { to_string_vec(options.property_keys, options.property_len) };
84+
let prop_vals = unsafe { to_string_vec(options.property_vals, options.property_len) };
8585

8686
let object_store = make_object_store(&uri, &prop_keys, &prop_vals)?;
8787

@@ -106,8 +106,7 @@ pub unsafe extern "C-unwind" fn vx_file_extract_statistics(
106106
file: *mut vx_file_reader,
107107
) -> *mut vx_file_statistics {
108108
Box::into_raw(Box::new(vx_file_statistics {
109-
num_rows: file
110-
.as_ref()
109+
num_rows: unsafe { file.as_ref() }
111110
.vortex_expect("null file ptr")
112111
.inner
113112
.row_count(),
@@ -117,14 +116,14 @@ pub unsafe extern "C-unwind" fn vx_file_extract_statistics(
117116
#[unsafe(no_mangle)]
118117
pub unsafe extern "C-unwind" fn vx_file_statistics_free(stat: *mut vx_file_statistics) {
119118
assert!(!stat.is_null());
120-
drop(Box::from_raw(stat));
119+
drop(unsafe { Box::from_raw(stat) });
121120
}
122121

123122
/// Get the DType of the data inside of the file.
124123
#[unsafe(no_mangle)]
125124
pub unsafe extern "C-unwind" fn vx_file_dtype(file: *const vx_file_reader) -> *mut DType {
126125
Box::into_raw(Box::new(
127-
file.as_ref()
126+
unsafe { file.as_ref() }
128127
.vortex_expect("null file")
129128
.inner
130129
.dtype()
@@ -143,11 +142,11 @@ pub unsafe extern "C-unwind" fn vx_file_scan(
143142
let file = unsafe { file.as_ref().vortex_expect("null file") };
144143
let mut stream = file.inner.scan().vortex_expect("create scan");
145144

146-
if let Some(opts) = opts.as_ref() {
145+
if let Some(opts) = unsafe { opts.as_ref() } {
147146
let mut field_names = Vec::new();
148147
for i in 0..opts.projection_len {
149148
let col_name = unsafe { *opts.projection.offset(i as isize) };
150-
let col_name: Arc<str> = to_string(col_name).into();
149+
let col_name: Arc<str> = unsafe { to_string(col_name) }.into();
151150
field_names.push(col_name);
152151
}
153152
let expr_str = opts.filter_expression;
@@ -188,7 +187,7 @@ pub unsafe extern "C-unwind" fn vx_file_scan(
188187
/// this file.
189188
#[unsafe(no_mangle)]
190189
pub unsafe extern "C-unwind" fn vx_file_reader_free(file: *mut vx_file_reader) {
191-
drop(Box::from_raw(file));
190+
drop(unsafe { Box::from_raw(file) });
192191
}
193192

194193
fn make_object_store(

vortex-ffi/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(unsafe_op_in_unsafe_fn, clippy::missing_safety_doc, clippy::panic)]
1+
#![allow(clippy::missing_safety_doc)]
22

33
//! Native interface to Vortex arrays, types, files and streams.
44
@@ -32,12 +32,12 @@ static RUNTIME: LazyLock<Runtime> = LazyLock::new(|| {
3232
});
3333

3434
pub(crate) unsafe fn to_string(ptr: *const c_char) -> String {
35-
let c_str = CStr::from_ptr(ptr);
35+
let c_str = unsafe { CStr::from_ptr(ptr) };
3636
c_str.to_string_lossy().into_owned()
3737
}
3838

3939
pub(crate) unsafe fn to_string_vec(ptr: *const *const c_char, len: c_int) -> Vec<String> {
4040
(0..len)
41-
.map(|i| to_string(*ptr.offset(i as isize)))
41+
.map(|i| unsafe { to_string(*ptr.offset(i as isize)) })
4242
.collect()
4343
}

vortex-ffi/src/sink.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub unsafe extern "C-unwind" fn vx_array_sink_close(
7878
error: *mut *mut vx_error,
7979
) {
8080
try_or(error, (), || {
81-
let vx_array_sink { sink, writer } = *Box::from_raw(sink);
81+
let vx_array_sink { sink, writer } = *unsafe { Box::from_raw(sink) };
8282
drop(sink);
8383

8484
RUNTIME.block_on(async {

0 commit comments

Comments
 (0)