From b0367ba9a207954f89d6249b1998dedf750b9f18 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 15 Jun 2021 15:31:01 +0200 Subject: [PATCH] Add `unstable_extern_types` feature To see what changes we'd have to make in the library to use `extern type` (RFC-1861) (when it's is stabilized). Unfortunately had to change some usage of `ptr::null[_mut]` to `0 as *const/mut X`, see https://github.com/rust-lang/rust/issues/42847. --- Cargo.toml | 3 ++- src/cache.rs | 4 ++-- src/declare.rs | 7 +++---- src/lib.rs | 2 ++ src/message/apple/mod.rs | 4 ++-- src/message/gnustep.rs | 4 ++-- src/message/mod.rs | 16 ++++++++-------- src/rc/weak.rs | 5 ++--- src/runtime.rs | 6 ++++++ 9 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3a7f2b8c2..63b5ff164 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,11 @@ exclude = [ [features] exception = ["objc_exception"] verify_message = [] +unstable_extern_types = [] [dependencies] malloc_buf = "1.0" -objc-encode = "1.0" +objc-encode = { git = "https://github.com/madsmtm/rust-objc-encode", branch = "unsized" } [dependencies.objc_exception] version = "0.1" diff --git a/src/cache.rs b/src/cache.rs index 14bf98182..c60307d18 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -38,7 +38,7 @@ impl CachedSel { /// Allows storing a `Class` reference in a static and lazily loading it. #[doc(hidden)] pub struct CachedClass { - ptr: AtomicPtr + ptr: AtomicPtr } impl CachedClass { @@ -60,7 +60,7 @@ impl CachedClass { self.ptr.store(cls as *mut _, Ordering::Relaxed); cls.as_ref() } else { - Some(&*ptr) + Some(&*(ptr as *const Class)) } } } diff --git a/src/declare.rs b/src/declare.rs index 729a650aa..43082266e 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -36,7 +36,6 @@ decl.register(); use std::ffi::CString; use std::mem; -use std::ptr; use crate::runtime::{BOOL, Class, Imp, NO, Object, Protocol, Sel, self}; use crate::{Encode, EncodeArguments, Encoding, Message}; @@ -44,7 +43,7 @@ use crate::{Encode, EncodeArguments, Encoding, Message}; /// Types that can be used as the implementation of an Objective-C method. pub trait MethodImplementation { /// The callee type of the method. - type Callee: Message; + type Callee: ?Sized + Message; /// The return type of the method. type Ret: Encode; /// The argument types of the method. @@ -57,7 +56,7 @@ pub trait MethodImplementation { macro_rules! method_decl_impl { (-$s:ident, $r:ident, $f:ty, $($t:ident),*) => ( impl<$s, $r $(, $t)*> MethodImplementation for $f - where $s: Message, $r: Encode $(, $t: Encode)* { + where $s: ?Sized + Message, $r: Encode $(, $t: Encode)* { type Callee = $s; type Ret = $r; type Args = ($($t,)*); @@ -120,7 +119,7 @@ impl ClassDecl { fn with_superclass(name: &str, superclass: Option<&Class>) -> Option { let name = CString::new(name).unwrap(); - let super_ptr = superclass.map_or(ptr::null(), |c| c); + let super_ptr = superclass.map_or(0 as *const Class, |c| c); let cls = unsafe { runtime::objc_allocateClassPair(super_ptr, name.as_ptr(), 0) }; diff --git a/src/lib.rs b/src/lib.rs index 5f2d4e9f1..a4b13bf99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,6 +63,8 @@ The bindings can be used on Linux or *BSD utilizing the #![crate_name = "objc"] #![crate_type = "lib"] +#![cfg_attr(feature = "unstable_extern_types", feature(extern_types))] + #![warn(missing_docs)] extern crate malloc_buf; diff --git a/src/message/apple/mod.rs b/src/message/apple/mod.rs index 34b6f14c0..94f230071 100644 --- a/src/message/apple/mod.rs +++ b/src/message/apple/mod.rs @@ -20,7 +20,7 @@ use self::arch::{msg_send_fn, msg_send_super_fn}; pub unsafe fn send_unverified(obj: *const T, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { let receiver = obj as *mut T as *mut Object; let msg_send_fn = msg_send_fn::(); objc_try!({ @@ -30,7 +30,7 @@ pub unsafe fn send_unverified(obj: *const T, sel: Sel, args: A) pub unsafe fn send_super_unverified(obj: *const T, superclass: &Class, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { let sup = Super { receiver: obj as *mut T as *mut Object, superclass: superclass }; let receiver = &sup as *const Super as *mut Object; let msg_send_fn = msg_send_super_fn::(); diff --git a/src/message/gnustep.rs b/src/message/gnustep.rs index 382ef8625..7ef4a5461 100644 --- a/src/message/gnustep.rs +++ b/src/message/gnustep.rs @@ -11,7 +11,7 @@ extern { pub unsafe fn send_unverified(obj: *const T, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { if obj.is_null() { return mem::zeroed(); } @@ -25,7 +25,7 @@ pub unsafe fn send_unverified(obj: *const T, sel: Sel, args: A) pub unsafe fn send_super_unverified(obj: *const T, superclass: &Class, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { let receiver = obj as *mut T as *mut Object; let sup = Super { receiver: receiver, superclass: superclass }; let msg_send_fn = objc_msg_lookup_super(&sup, sel); diff --git a/src/message/mod.rs b/src/message/mod.rs index 86f80dcee..d144aa3a9 100644 --- a/src/message/mod.rs +++ b/src/message/mod.rs @@ -61,14 +61,14 @@ pub unsafe trait Message { #[cfg(not(feature = "verify_message"))] unsafe fn send_message(&self, sel: Sel, args: A) -> Result - where Self: Sized, A: MessageArguments, R: Any { + where A: MessageArguments, R: Any { send_message(self, sel, args) } #[cfg(feature = "verify_message")] unsafe fn send_message(&self, sel: Sel, args: A) -> Result - where Self: Sized, A: MessageArguments + EncodeArguments, + where A: MessageArguments + EncodeArguments, R: Any + Encode { send_message(self, sel, args) } @@ -97,7 +97,7 @@ pub unsafe trait Message { ``` */ fn verify_message(&self, sel: Sel) -> Result<(), MessageError> - where Self: Sized, A: EncodeArguments, R: Encode { + where A: EncodeArguments, R: Encode { let obj = unsafe { &*(self as *const _ as *const Object) }; verify_message_signature::(obj.class(), sel) .map_err(MessageError::from) @@ -181,7 +181,7 @@ impl<'a> From> for MessageError { #[cfg(not(feature = "verify_message"))] pub unsafe fn send_message(obj: *const T, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { send_unverified(obj, sel, args) } @@ -190,7 +190,7 @@ pub unsafe fn send_message(obj: *const T, sel: Sel, args: A) #[cfg(feature = "verify_message")] pub unsafe fn send_message(obj: *const T, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments + EncodeArguments, + where T: ?Sized + Message, A: MessageArguments + EncodeArguments, R: Any + Encode { let cls = if obj.is_null() { return Err(VerificationError::NilReceiver(sel).into()); @@ -207,7 +207,7 @@ pub unsafe fn send_message(obj: *const T, sel: Sel, args: A) #[cfg(not(feature = "verify_message"))] pub unsafe fn send_super_message(obj: *const T, superclass: &Class, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments, R: Any { + where T: ?Sized + Message, A: MessageArguments, R: Any { send_super_unverified(obj, superclass, sel, args) } @@ -216,7 +216,7 @@ pub unsafe fn send_super_message(obj: *const T, superclass: &Class, #[cfg(feature = "verify_message")] pub unsafe fn send_super_message(obj: *const T, superclass: &Class, sel: Sel, args: A) -> Result - where T: Message, A: MessageArguments + EncodeArguments, + where T: ?Sized + Message, A: MessageArguments + EncodeArguments, R: Any + Encode { if obj.is_null() { return Err(VerificationError::NilReceiver(sel).into()); @@ -255,7 +255,7 @@ mod tests { #[cfg(not(feature = "verify_message"))] #[test] fn test_send_message_nil() { - let nil: *mut Object = ::std::ptr::null_mut(); + let nil = 0 as *mut Object; let result: usize = unsafe { msg_send![nil, hash] }; diff --git a/src/rc/weak.rs b/src/rc/weak.rs index aa2f693e6..f5ac5d4ee 100644 --- a/src/rc/weak.rs +++ b/src/rc/weak.rs @@ -1,5 +1,4 @@ use std::cell::UnsafeCell; -use std::ptr; use crate::runtime::{Object, self}; use super::StrongPtr; @@ -16,7 +15,7 @@ impl WeakPtr { /// Constructs a `WeakPtr` to the given object. /// Unsafe because the caller must ensure the given object pointer is valid. pub unsafe fn new(obj: *mut Object) -> Self { - let ptr = Box::new(UnsafeCell::new(ptr::null_mut())); + let ptr = Box::new(UnsafeCell::new(0 as *mut Object)); runtime::objc_initWeak(ptr.get(), obj); WeakPtr(ptr) } @@ -41,7 +40,7 @@ impl Drop for WeakPtr { impl Clone for WeakPtr { fn clone(&self) -> Self { - let ptr = Box::new(UnsafeCell::new(ptr::null_mut())); + let ptr = Box::new(UnsafeCell::new(0 as *mut Object)); unsafe { runtime::objc_copyWeak(ptr.get(), self.0.get()); } diff --git a/src/runtime.rs b/src/runtime.rs index dd8f3aa09..8d56ff37c 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -39,8 +39,14 @@ pub struct Sel { /// A marker type to be embedded into other types just so that they cannot be /// constructed externally. +#[cfg(not(feature = "unstable_extern_types"))] type PrivateMarker = [u8; 0]; +#[cfg(feature = "unstable_extern_types")] +extern { + type PrivateMarker; +} + /// A type that represents an instance variable. #[repr(C)] pub struct Ivar {