Skip to content

Commit b8f9b88

Browse files
committed
Don't use as for casting pointers (only for *const T -> *mut T)
Easy to accidentally convert immutable pointers to a mutable ones, as is done in `declare` (now fixed).
1 parent 9151c50 commit b8f9b88

File tree

14 files changed

+129
-100
lines changed

14 files changed

+129
-100
lines changed

objc2-foundation/src/data.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ impl NSData {
5353

5454
pub fn bytes(&self) -> &[u8] {
5555
let ptr: *const c_void = unsafe { msg_send![self, bytes] };
56+
let ptr: *const u8 = ptr.cast();
5657
// The bytes pointer may be null for length zero
5758
if ptr.is_null() {
5859
&[]
5960
} else {
60-
unsafe { slice::from_raw_parts(ptr as *const u8, self.len()) }
61+
unsafe { slice::from_raw_parts(ptr, self.len()) }
6162
}
6263
}
6364

@@ -172,11 +173,12 @@ impl NSMutableData {
172173
#[doc(alias = "mutableBytes")]
173174
pub fn bytes_mut(&mut self) -> &mut [u8] {
174175
let ptr = self.raw_bytes_mut();
176+
let ptr: *mut u8 = ptr.cast();
175177
// The bytes pointer may be null for length zero
176178
if ptr.is_null() {
177179
&mut []
178180
} else {
179-
unsafe { slice::from_raw_parts_mut(ptr as *mut u8, self.len()) }
181+
unsafe { slice::from_raw_parts_mut(ptr, self.len()) }
180182
}
181183
}
182184

@@ -188,7 +190,7 @@ impl NSMutableData {
188190

189191
#[doc(alias = "appendBytes:length:")]
190192
pub fn extend_from_slice(&mut self, bytes: &[u8]) {
191-
let bytes_ptr = bytes.as_ptr() as *const c_void;
193+
let bytes_ptr: *const c_void = bytes.as_ptr().cast();
192194
unsafe { msg_send![self, appendBytes: bytes_ptr, length: bytes.len()] }
193195
}
194196

@@ -201,7 +203,7 @@ impl NSMutableData {
201203
let range = NSRange::from(range);
202204
// No need to verify the length of the range here,
203205
// `replaceBytesInRange:` just zero-fills if out of bounds.
204-
let ptr = bytes.as_ptr() as *const c_void;
206+
let ptr: *const c_void = bytes.as_ptr().cast();
205207
unsafe {
206208
msg_send![
207209
self,
@@ -312,7 +314,7 @@ impl DefaultId for NSMutableData {
312314
}
313315

314316
unsafe fn data_with_bytes(cls: &Class, bytes: &[u8]) -> *mut Object {
315-
let bytes_ptr = bytes.as_ptr() as *const c_void;
317+
let bytes_ptr: *const c_void = bytes.as_ptr().cast();
316318
unsafe {
317319
let obj: *mut Object = msg_send![cls, alloc];
318320
msg_send![
@@ -333,18 +335,19 @@ unsafe fn data_from_vec(cls: &Class, bytes: Vec<u8>) -> *mut Object {
333335

334336
let dealloc = ConcreteBlock::new(move |bytes: *mut c_void, len: usize| unsafe {
335337
// Recreate the Vec and let it drop
336-
let _ = Vec::from_raw_parts(bytes as *mut u8, len, capacity);
338+
let _ = Vec::<u8>::from_raw_parts(bytes.cast(), len, capacity);
337339
});
338340
let dealloc = dealloc.copy();
339341
let dealloc: &Block<(*mut c_void, usize), ()> = &dealloc;
340342

341343
let mut bytes = ManuallyDrop::new(bytes);
344+
let bytes_ptr: *mut c_void = bytes.as_mut_ptr().cast();
342345

343346
unsafe {
344347
let obj: *mut Object = msg_send![cls, alloc];
345348
msg_send![
346349
obj,
347-
initWithBytesNoCopy: bytes.as_mut_ptr() as *mut c_void,
350+
initWithBytesNoCopy: bytes_ptr,
348351
length: bytes.len(),
349352
deallocator: dealloc,
350353
]

objc2-foundation/src/enumerator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,25 +172,25 @@ mod tests {
172172

173173
#[test]
174174
fn test_enumerator() {
175-
let vec = (0u32..4).map(NSValue::new).collect();
175+
let vec = (0usize..4).map(NSValue::new).collect();
176176
let array = NSArray::from_vec(vec);
177177

178178
let enumerator = array.iter();
179179
assert_eq!(enumerator.count(), 4);
180180

181181
let enumerator = array.iter();
182-
assert!(enumerator.enumerate().all(|(i, obj)| obj.get() == i as u32));
182+
assert!(enumerator.enumerate().all(|(i, obj)| obj.get() == i));
183183
}
184184

185185
#[test]
186186
fn test_fast_enumerator() {
187-
let vec = (0u32..4).map(NSValue::new).collect();
187+
let vec = (0usize..4).map(NSValue::new).collect();
188188
let array = NSArray::from_vec(vec);
189189

190190
let enumerator = array.iter_fast();
191191
assert_eq!(enumerator.count(), 4);
192192

193193
let enumerator = array.iter_fast();
194-
assert!(enumerator.enumerate().all(|(i, obj)| obj.get() == i as u32));
194+
assert!(enumerator.enumerate().all(|(i, obj)| obj.get() == i));
195195
}
196196
}

objc2-foundation/src/string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl NSString {
140140
//
141141
// https://developer.apple.com/documentation/foundation/nsstring/1411189-utf8string?language=objc
142142
let bytes: *const c_char = unsafe { msg_send![self, UTF8String] };
143-
let bytes = bytes as *const u8;
143+
let bytes: *const u8 = bytes.cast();
144144
let len = self.len();
145145

146146
// SAFETY:
@@ -199,7 +199,7 @@ impl NSString {
199199
}
200200

201201
pub(crate) fn from_str(cls: &Class, string: &str) -> *mut Object {
202-
let bytes = string.as_ptr() as *const c_void;
202+
let bytes: *const c_void = string.as_ptr().cast();
203203
unsafe {
204204
let obj: *mut Object = msg_send![cls, alloc];
205205
msg_send![

objc2-foundation/src/value.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<T: 'static + Copy + Encode> NSValue<T> {
5252
/// The user must ensure that the inner value is properly initialized.
5353
pub unsafe fn get_unchecked(&self) -> T {
5454
let mut value = MaybeUninit::<T>::uninit();
55-
let ptr = value.as_mut_ptr() as *mut c_void;
55+
let ptr: *mut c_void = value.as_mut_ptr().cast();
5656
let _: () = unsafe { msg_send![self, getValue: ptr] };
5757
unsafe { value.assume_init() }
5858
}
@@ -64,7 +64,8 @@ impl<T: 'static + Copy + Encode> NSValue<T> {
6464

6565
pub fn new(value: T) -> Id<Self, Shared> {
6666
let cls = Self::class();
67-
let bytes = &value as *const T as *const c_void;
67+
let bytes: *const T = &value;
68+
let bytes: *const c_void = bytes.cast();
6869
let encoding = CString::new(T::ENCODING.to_string()).unwrap();
6970
unsafe {
7071
let obj: *mut Self = msg_send![cls, alloc];

objc2/examples/talk_to_me.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ fn main() {
1414
const UTF8_ENCODING: NSUInteger = 4;
1515

1616
let string: *const Object = unsafe { msg_send![class!(NSString), alloc] };
17+
let text_ptr: *const c_void = text.as_ptr().cast();
1718
let string = unsafe {
1819
msg_send![
1920
string,
20-
initWithBytes: text.as_ptr() as *const c_void,
21+
initWithBytes: text_ptr,
2122
length: text.len(),
2223
encoding: UTF8_ENCODING,
2324
]

objc2/src/cache.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ impl CachedSel {
2727
// `Relaxed` should be fine since `sel_registerName` is thread-safe.
2828
let ptr = self.ptr.load(Ordering::Relaxed);
2929
if ptr.is_null() {
30-
let ptr = unsafe { ffi::sel_registerName(name.as_ptr() as *const _) };
31-
self.ptr.store(ptr as *mut _, Ordering::Relaxed);
32-
unsafe { Sel::from_ptr(ptr as *const _) }
30+
let ptr: *const c_void = unsafe { ffi::sel_registerName(name.as_ptr().cast()).cast() };
31+
self.ptr.store(ptr as *mut c_void, Ordering::Relaxed);
32+
unsafe { Sel::from_ptr(ptr) }
3333
} else {
3434
unsafe { Sel::from_ptr(ptr) }
3535
}
@@ -58,8 +58,8 @@ impl CachedClass {
5858
// `Relaxed` should be fine since `objc_getClass` is thread-safe.
5959
let ptr = self.ptr.load(Ordering::Relaxed);
6060
if ptr.is_null() {
61-
let cls = unsafe { ffi::objc_getClass(name.as_ptr() as *const _) } as *const Class;
62-
self.ptr.store(cls as *mut _, Ordering::Relaxed);
61+
let cls: *const Class = unsafe { ffi::objc_getClass(name.as_ptr().cast()) }.cast();
62+
self.ptr.store(cls as *mut Class, Ordering::Relaxed);
6363
unsafe { cls.as_ref() }
6464
} else {
6565
Some(unsafe { &*ptr })

objc2/src/declare.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,13 @@ unsafe impl Send for ClassBuilder {}
186186
unsafe impl Sync for ClassBuilder {}
187187

188188
impl ClassBuilder {
189-
fn as_ptr(&self) -> *mut ffi::objc_class {
189+
fn as_mut_ptr(&mut self) -> *mut ffi::objc_class {
190190
self.cls.as_ptr().cast()
191191
}
192192

193193
fn with_superclass(name: &str, superclass: Option<&Class>) -> Option<Self> {
194194
let name = CString::new(name).unwrap();
195-
let super_ptr = superclass.map_or(ptr::null(), |c| c) as _;
195+
let super_ptr = superclass.map_or(ptr::null(), |c| c).cast();
196196
let cls = unsafe { ffi::objc_allocateClassPair(super_ptr, name.as_ptr(), 0) };
197197
NonNull::new(cls.cast()).map(|cls| Self { cls })
198198
}
@@ -255,15 +255,19 @@ impl ClassBuilder {
255255
let types = method_type_encoding(&F::Ret::ENCODING, encs);
256256
let success = Bool::from_raw(unsafe {
257257
ffi::class_addMethod(
258-
self.as_ptr(),
259-
sel.as_ptr() as _,
258+
self.as_mut_ptr(),
259+
sel.as_ptr().cast(),
260260
Some(func.__imp()),
261261
types.as_ptr(),
262262
)
263263
});
264264
assert!(success.as_bool(), "Failed to add method {:?}", sel);
265265
}
266266

267+
fn metaclass_mut(&mut self) -> *mut ffi::objc_class {
268+
unsafe { ffi::object_getClass(self.as_mut_ptr().cast()) as *mut ffi::objc_class }
269+
}
270+
267271
/// Adds a class method with the given name and implementation.
268272
///
269273
/// # Panics
@@ -290,11 +294,10 @@ impl ClassBuilder {
290294
);
291295

292296
let types = method_type_encoding(&F::Ret::ENCODING, encs);
293-
let metaclass = unsafe { self.cls.as_ref() }.metaclass() as *const _ as *mut _;
294297
let success = Bool::from_raw(unsafe {
295298
ffi::class_addMethod(
296-
metaclass,
297-
sel.as_ptr() as _,
299+
self.metaclass_mut(),
300+
sel.as_ptr().cast(),
298301
Some(func.__imp()),
299302
types.as_ptr(),
300303
)
@@ -314,7 +317,7 @@ impl ClassBuilder {
314317
let align = log2_align_of::<T>();
315318
let success = Bool::from_raw(unsafe {
316319
ffi::class_addIvar(
317-
self.as_ptr(),
320+
self.as_mut_ptr(),
318321
c_name.as_ptr(),
319322
size,
320323
align,
@@ -330,7 +333,7 @@ impl ClassBuilder {
330333
///
331334
/// If the protocol wasn't successfully added.
332335
pub fn add_protocol(&mut self, proto: &Protocol) {
333-
let success = unsafe { ffi::class_addProtocol(self.as_ptr(), proto.as_ptr()) };
336+
let success = unsafe { ffi::class_addProtocol(self.as_mut_ptr(), proto.as_ptr()) };
334337
let success = Bool::from_raw(success).as_bool();
335338
assert!(success, "Failed to add protocol {:?}", proto);
336339
}
@@ -341,15 +344,15 @@ impl ClassBuilder {
341344
/// to the newly registered [`Class`].
342345
pub fn register(self) -> &'static Class {
343346
// Forget self, otherwise the class will be disposed in drop
344-
let cls = ManuallyDrop::new(self).cls;
345-
unsafe { ffi::objc_registerClassPair(cls.as_ptr().cast()) };
346-
unsafe { cls.as_ref() }
347+
let mut this = ManuallyDrop::new(self);
348+
unsafe { ffi::objc_registerClassPair(this.as_mut_ptr()) };
349+
unsafe { this.cls.as_ref() }
347350
}
348351
}
349352

350353
impl Drop for ClassBuilder {
351354
fn drop(&mut self) {
352-
unsafe { ffi::objc_disposeClassPair(self.as_ptr()) }
355+
unsafe { ffi::objc_disposeClassPair(self.as_mut_ptr()) }
353356
}
354357
}
355358

@@ -369,7 +372,7 @@ unsafe impl Send for ProtocolBuilder {}
369372
unsafe impl Sync for ProtocolBuilder {}
370373

371374
impl ProtocolBuilder {
372-
fn as_ptr(&self) -> *mut ffi::objc_protocol {
375+
fn as_mut_ptr(&mut self) -> *mut ffi::objc_protocol {
373376
self.proto.as_ptr().cast()
374377
}
375378

@@ -378,8 +381,8 @@ impl ProtocolBuilder {
378381
/// Returns [`None`] if the protocol couldn't be allocated.
379382
pub fn new(name: &str) -> Option<Self> {
380383
let c_name = CString::new(name).unwrap();
381-
let proto = unsafe { ffi::objc_allocateProtocol(c_name.as_ptr()) } as *mut Protocol;
382-
NonNull::new(proto).map(|proto| Self { proto })
384+
let proto = unsafe { ffi::objc_allocateProtocol(c_name.as_ptr()) };
385+
NonNull::new(proto.cast()).map(|proto| Self { proto })
383386
}
384387

385388
fn add_method_description_common<Args, Ret>(
@@ -403,8 +406,8 @@ impl ProtocolBuilder {
403406
let types = method_type_encoding(&Ret::ENCODING, encs);
404407
unsafe {
405408
ffi::protocol_addMethodDescription(
406-
self.as_ptr(),
407-
sel.as_ptr() as _,
409+
self.as_mut_ptr(),
410+
sel.as_ptr().cast(),
408411
types.as_ptr(),
409412
Bool::new(is_required).as_raw(),
410413
Bool::new(is_instance_method).as_raw(),
@@ -433,15 +436,15 @@ impl ProtocolBuilder {
433436
/// Adds a requirement on another protocol.
434437
pub fn add_protocol(&mut self, proto: &Protocol) {
435438
unsafe {
436-
ffi::protocol_addProtocol(self.as_ptr(), proto.as_ptr());
439+
ffi::protocol_addProtocol(self.as_mut_ptr(), proto.as_ptr());
437440
}
438441
}
439442

440443
/// Registers the [`ProtocolBuilder`], consuming it and returning a reference
441444
/// to the newly registered [`Protocol`].
442-
pub fn register(self) -> &'static Protocol {
445+
pub fn register(mut self) -> &'static Protocol {
443446
unsafe {
444-
ffi::objc_registerProtocol(self.as_ptr());
447+
ffi::objc_registerProtocol(self.as_mut_ptr());
445448
self.proto.as_ref()
446449
}
447450
}

objc2/src/exception.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), Option<Id<Object, Sh
6060
let f: extern "C" fn(*mut c_void) = unsafe { mem::transmute(f) };
6161
// Wrap the closure in an Option so it can be taken
6262
let mut closure = Some(closure);
63-
let context = &mut closure as *mut _ as *mut c_void;
63+
let context: *mut Option<F> = &mut closure;
64+
let context = context.cast();
6465

6566
let mut exception = ptr::null_mut();
6667
let success = unsafe { ffi::rust_objc_sys_0_2_try_catch_exception(f, context, &mut exception) };
@@ -76,7 +77,7 @@ unsafe fn try_no_ret<F: FnOnce()>(closure: F) -> Result<(), Option<Id<Object, Sh
7677
// instance any more, and Rust code is forbidden by requiring a Shared
7778
// Id in `throw` (instead of just a shared reference, which could have
7879
// come from an Owned Id).
79-
Err(unsafe { Id::new(exception as *mut Object) })
80+
Err(unsafe { Id::new(exception.cast()) })
8081
}
8182
}
8283

@@ -146,8 +147,7 @@ mod tests {
146147
let obj: Id<Object, Shared> = unsafe { Id::new(msg_send![class!(NSObject), new]).unwrap() };
147148

148149
let result = unsafe { catch(|| throw(Some(&obj))) };
149-
let e = result.unwrap_err().unwrap();
150-
// Compare pointers
151-
assert_eq!(&*e as *const Object, &*obj as *const Object);
150+
let exception = result.unwrap_err().unwrap();
151+
assert!(ptr::eq(&*exception, &*obj));
152152
}
153153
}

objc2/src/message/apple/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ where
4848
A: MessageArguments,
4949
R: Encode,
5050
{
51-
let sup = ffi::objc_super {
52-
receiver: receiver as *mut _,
53-
super_class: superclass as *const Class as *const _,
51+
let superclass: *const Class = superclass;
52+
let mut sup = ffi::objc_super {
53+
receiver: receiver.cast(),
54+
super_class: superclass.cast(),
5455
};
55-
let receiver = &sup as *const ffi::objc_super as *mut Object;
56+
let receiver: *mut ffi::objc_super = &mut sup;
57+
let receiver = receiver.cast();
58+
5659
let msg_send_fn = R::MSG_SEND_SUPER;
5760
unsafe { conditional_try(|| A::__invoke(msg_send_fn, receiver, sel, args)) }
5861
}

objc2/src/message/gnustep.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ where
2323
return unsafe { mem::zeroed() };
2424
}
2525

26-
let sel_ptr = sel.as_ptr() as *const _;
27-
let msg_send_fn = unsafe { ffi::objc_msg_lookup(receiver as *mut _, sel_ptr) };
26+
let sel_ptr = sel.as_ptr().cast();
27+
let msg_send_fn = unsafe { ffi::objc_msg_lookup(receiver.cast(), sel_ptr) };
2828
let msg_send_fn = msg_send_fn.expect("Null IMP");
2929
unsafe { conditional_try(|| A::__invoke(msg_send_fn, receiver, sel, args)) }
3030
}
@@ -44,11 +44,12 @@ where
4444
return unsafe { mem::zeroed() };
4545
}
4646

47+
let superclass: *const Class = superclass;
4748
let sup = ffi::objc_super {
48-
receiver: receiver as *mut _,
49-
super_class: superclass as *const Class as *const _,
49+
receiver: receiver.cast(),
50+
super_class: superclass.cast(),
5051
};
51-
let sel_ptr = sel.as_ptr() as *const _;
52+
let sel_ptr = sel.as_ptr().cast();
5253
let msg_send_fn = unsafe { ffi::objc_msg_lookup_super(&sup, sel_ptr) };
5354
let msg_send_fn = msg_send_fn.expect("Null IMP");
5455
unsafe { conditional_try(|| A::__invoke(msg_send_fn, receiver, sel, args)) }

0 commit comments

Comments
 (0)