Skip to content

Commit

Permalink
Add unstable_extern_types feature
Browse files Browse the repository at this point in the history
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 rust-lang/rust#42847.
  • Loading branch information
madsmtm committed Jun 15, 2021
1 parent c8696b0 commit b0367ba
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 22 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Class>
ptr: AtomicPtr<c_void>
}

impl CachedClass {
Expand All @@ -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))
}
}
}
7 changes: 3 additions & 4 deletions src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@ 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};

/// 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.
Expand All @@ -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,)*);
Expand Down Expand Up @@ -120,7 +119,7 @@ impl ClassDecl {
fn with_superclass(name: &str, superclass: Option<&Class>)
-> Option<ClassDecl> {
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)
};
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/message/apple/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use self::arch::{msg_send_fn, msg_send_super_fn};

pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)
-> Result<R, MessageError>
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::<R>();
objc_try!({
Expand All @@ -30,7 +30,7 @@ pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)

pub unsafe fn send_super_unverified<T, A, R>(obj: *const T, superclass: &Class,
sel: Sel, args: A) -> Result<R, MessageError>
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::<R>();
Expand Down
4 changes: 2 additions & 2 deletions src/message/gnustep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern {

pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)
-> Result<R, MessageError>
where T: Message, A: MessageArguments, R: Any {
where T: ?Sized + Message, A: MessageArguments, R: Any {
if obj.is_null() {
return mem::zeroed();
}
Expand All @@ -25,7 +25,7 @@ pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)

pub unsafe fn send_super_unverified<T, A, R>(obj: *const T, superclass: &Class,
sel: Sel, args: A) -> Result<R, MessageError>
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);
Expand Down
16 changes: 8 additions & 8 deletions src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ pub unsafe trait Message {
#[cfg(not(feature = "verify_message"))]
unsafe fn send_message<A, R>(&self, sel: Sel, args: A)
-> Result<R, MessageError>
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<A, R>(&self, sel: Sel, args: A)
-> Result<R, MessageError>
where Self: Sized, A: MessageArguments + EncodeArguments,
where A: MessageArguments + EncodeArguments,
R: Any + Encode {
send_message(self, sel, args)
}
Expand Down Expand Up @@ -97,7 +97,7 @@ pub unsafe trait Message {
```
*/
fn verify_message<A, R>(&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::<A, R>(obj.class(), sel)
.map_err(MessageError::from)
Expand Down Expand Up @@ -181,7 +181,7 @@ impl<'a> From<VerificationError<'a>> for MessageError {
#[cfg(not(feature = "verify_message"))]
pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
-> Result<R, MessageError>
where T: Message, A: MessageArguments, R: Any {
where T: ?Sized + Message, A: MessageArguments, R: Any {
send_unverified(obj, sel, args)
}

Expand All @@ -190,7 +190,7 @@ pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
#[cfg(feature = "verify_message")]
pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
-> Result<R, MessageError>
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());
Expand All @@ -207,7 +207,7 @@ pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
#[cfg(not(feature = "verify_message"))]
pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
sel: Sel, args: A) -> Result<R, MessageError>
where T: Message, A: MessageArguments, R: Any {
where T: ?Sized + Message, A: MessageArguments, R: Any {
send_super_unverified(obj, superclass, sel, args)
}

Expand All @@ -216,7 +216,7 @@ pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
#[cfg(feature = "verify_message")]
pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
sel: Sel, args: A) -> Result<R, MessageError>
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());
Expand Down Expand Up @@ -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]
};
Expand Down
5 changes: 2 additions & 3 deletions src/rc/weak.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::cell::UnsafeCell;
use std::ptr;

use crate::runtime::{Object, self};
use super::StrongPtr;
Expand All @@ -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)
}
Expand All @@ -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());
}
Expand Down
6 changes: 6 additions & 0 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit b0367ba

Please sign in to comment.