Skip to content

Commit b0367ba

Browse files
committed
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 rust-lang/rust#42847.
1 parent c8696b0 commit b0367ba

File tree

9 files changed

+29
-22
lines changed

9 files changed

+29
-22
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ exclude = [
2323
[features]
2424
exception = ["objc_exception"]
2525
verify_message = []
26+
unstable_extern_types = []
2627

2728
[dependencies]
2829
malloc_buf = "1.0"
29-
objc-encode = "1.0"
30+
objc-encode = { git = "https://github.com/madsmtm/rust-objc-encode", branch = "unsized" }
3031

3132
[dependencies.objc_exception]
3233
version = "0.1"

src/cache.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl CachedSel {
3838
/// Allows storing a `Class` reference in a static and lazily loading it.
3939
#[doc(hidden)]
4040
pub struct CachedClass {
41-
ptr: AtomicPtr<Class>
41+
ptr: AtomicPtr<c_void>
4242
}
4343

4444
impl CachedClass {
@@ -60,7 +60,7 @@ impl CachedClass {
6060
self.ptr.store(cls as *mut _, Ordering::Relaxed);
6161
cls.as_ref()
6262
} else {
63-
Some(&*ptr)
63+
Some(&*(ptr as *const Class))
6464
}
6565
}
6666
}

src/declare.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,14 @@ decl.register();
3636

3737
use std::ffi::CString;
3838
use std::mem;
39-
use std::ptr;
4039

4140
use crate::runtime::{BOOL, Class, Imp, NO, Object, Protocol, Sel, self};
4241
use crate::{Encode, EncodeArguments, Encoding, Message};
4342

4443
/// Types that can be used as the implementation of an Objective-C method.
4544
pub trait MethodImplementation {
4645
/// The callee type of the method.
47-
type Callee: Message;
46+
type Callee: ?Sized + Message;
4847
/// The return type of the method.
4948
type Ret: Encode;
5049
/// The argument types of the method.
@@ -57,7 +56,7 @@ pub trait MethodImplementation {
5756
macro_rules! method_decl_impl {
5857
(-$s:ident, $r:ident, $f:ty, $($t:ident),*) => (
5958
impl<$s, $r $(, $t)*> MethodImplementation for $f
60-
where $s: Message, $r: Encode $(, $t: Encode)* {
59+
where $s: ?Sized + Message, $r: Encode $(, $t: Encode)* {
6160
type Callee = $s;
6261
type Ret = $r;
6362
type Args = ($($t,)*);
@@ -120,7 +119,7 @@ impl ClassDecl {
120119
fn with_superclass(name: &str, superclass: Option<&Class>)
121120
-> Option<ClassDecl> {
122121
let name = CString::new(name).unwrap();
123-
let super_ptr = superclass.map_or(ptr::null(), |c| c);
122+
let super_ptr = superclass.map_or(0 as *const Class, |c| c);
124123
let cls = unsafe {
125124
runtime::objc_allocateClassPair(super_ptr, name.as_ptr(), 0)
126125
};

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ The bindings can be used on Linux or *BSD utilizing the
6363
#![crate_name = "objc"]
6464
#![crate_type = "lib"]
6565

66+
#![cfg_attr(feature = "unstable_extern_types", feature(extern_types))]
67+
6668
#![warn(missing_docs)]
6769

6870
extern crate malloc_buf;

src/message/apple/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use self::arch::{msg_send_fn, msg_send_super_fn};
2020

2121
pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)
2222
-> Result<R, MessageError>
23-
where T: Message, A: MessageArguments, R: Any {
23+
where T: ?Sized + Message, A: MessageArguments, R: Any {
2424
let receiver = obj as *mut T as *mut Object;
2525
let msg_send_fn = msg_send_fn::<R>();
2626
objc_try!({
@@ -30,7 +30,7 @@ pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A)
3030

3131
pub unsafe fn send_super_unverified<T, A, R>(obj: *const T, superclass: &Class,
3232
sel: Sel, args: A) -> Result<R, MessageError>
33-
where T: Message, A: MessageArguments, R: Any {
33+
where T: ?Sized + Message, A: MessageArguments, R: Any {
3434
let sup = Super { receiver: obj as *mut T as *mut Object, superclass: superclass };
3535
let receiver = &sup as *const Super as *mut Object;
3636
let msg_send_fn = msg_send_super_fn::<R>();

src/message/gnustep.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern {
1111

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

2626
pub unsafe fn send_super_unverified<T, A, R>(obj: *const T, superclass: &Class,
2727
sel: Sel, args: A) -> Result<R, MessageError>
28-
where T: Message, A: MessageArguments, R: Any {
28+
where T: ?Sized + Message, A: MessageArguments, R: Any {
2929
let receiver = obj as *mut T as *mut Object;
3030
let sup = Super { receiver: receiver, superclass: superclass };
3131
let msg_send_fn = objc_msg_lookup_super(&sup, sel);

src/message/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ pub unsafe trait Message {
6161
#[cfg(not(feature = "verify_message"))]
6262
unsafe fn send_message<A, R>(&self, sel: Sel, args: A)
6363
-> Result<R, MessageError>
64-
where Self: Sized, A: MessageArguments, R: Any {
64+
where A: MessageArguments, R: Any {
6565
send_message(self, sel, args)
6666
}
6767

6868
#[cfg(feature = "verify_message")]
6969
unsafe fn send_message<A, R>(&self, sel: Sel, args: A)
7070
-> Result<R, MessageError>
71-
where Self: Sized, A: MessageArguments + EncodeArguments,
71+
where A: MessageArguments + EncodeArguments,
7272
R: Any + Encode {
7373
send_message(self, sel, args)
7474
}
@@ -97,7 +97,7 @@ pub unsafe trait Message {
9797
```
9898
*/
9999
fn verify_message<A, R>(&self, sel: Sel) -> Result<(), MessageError>
100-
where Self: Sized, A: EncodeArguments, R: Encode {
100+
where A: EncodeArguments, R: Encode {
101101
let obj = unsafe { &*(self as *const _ as *const Object) };
102102
verify_message_signature::<A, R>(obj.class(), sel)
103103
.map_err(MessageError::from)
@@ -181,7 +181,7 @@ impl<'a> From<VerificationError<'a>> for MessageError {
181181
#[cfg(not(feature = "verify_message"))]
182182
pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
183183
-> Result<R, MessageError>
184-
where T: Message, A: MessageArguments, R: Any {
184+
where T: ?Sized + Message, A: MessageArguments, R: Any {
185185
send_unverified(obj, sel, args)
186186
}
187187

@@ -190,7 +190,7 @@ pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
190190
#[cfg(feature = "verify_message")]
191191
pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
192192
-> Result<R, MessageError>
193-
where T: Message, A: MessageArguments + EncodeArguments,
193+
where T: ?Sized + Message, A: MessageArguments + EncodeArguments,
194194
R: Any + Encode {
195195
let cls = if obj.is_null() {
196196
return Err(VerificationError::NilReceiver(sel).into());
@@ -207,7 +207,7 @@ pub unsafe fn send_message<T, A, R>(obj: *const T, sel: Sel, args: A)
207207
#[cfg(not(feature = "verify_message"))]
208208
pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
209209
sel: Sel, args: A) -> Result<R, MessageError>
210-
where T: Message, A: MessageArguments, R: Any {
210+
where T: ?Sized + Message, A: MessageArguments, R: Any {
211211
send_super_unverified(obj, superclass, sel, args)
212212
}
213213

@@ -216,7 +216,7 @@ pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
216216
#[cfg(feature = "verify_message")]
217217
pub unsafe fn send_super_message<T, A, R>(obj: *const T, superclass: &Class,
218218
sel: Sel, args: A) -> Result<R, MessageError>
219-
where T: Message, A: MessageArguments + EncodeArguments,
219+
where T: ?Sized + Message, A: MessageArguments + EncodeArguments,
220220
R: Any + Encode {
221221
if obj.is_null() {
222222
return Err(VerificationError::NilReceiver(sel).into());
@@ -255,7 +255,7 @@ mod tests {
255255
#[cfg(not(feature = "verify_message"))]
256256
#[test]
257257
fn test_send_message_nil() {
258-
let nil: *mut Object = ::std::ptr::null_mut();
258+
let nil = 0 as *mut Object;
259259
let result: usize = unsafe {
260260
msg_send![nil, hash]
261261
};

src/rc/weak.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::cell::UnsafeCell;
2-
use std::ptr;
32

43
use crate::runtime::{Object, self};
54
use super::StrongPtr;
@@ -16,7 +15,7 @@ impl WeakPtr {
1615
/// Constructs a `WeakPtr` to the given object.
1716
/// Unsafe because the caller must ensure the given object pointer is valid.
1817
pub unsafe fn new(obj: *mut Object) -> Self {
19-
let ptr = Box::new(UnsafeCell::new(ptr::null_mut()));
18+
let ptr = Box::new(UnsafeCell::new(0 as *mut Object));
2019
runtime::objc_initWeak(ptr.get(), obj);
2120
WeakPtr(ptr)
2221
}
@@ -41,7 +40,7 @@ impl Drop for WeakPtr {
4140

4241
impl Clone for WeakPtr {
4342
fn clone(&self) -> Self {
44-
let ptr = Box::new(UnsafeCell::new(ptr::null_mut()));
43+
let ptr = Box::new(UnsafeCell::new(0 as *mut Object));
4544
unsafe {
4645
runtime::objc_copyWeak(ptr.get(), self.0.get());
4746
}

src/runtime.rs

+6
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ pub struct Sel {
3939

4040
/// A marker type to be embedded into other types just so that they cannot be
4141
/// constructed externally.
42+
#[cfg(not(feature = "unstable_extern_types"))]
4243
type PrivateMarker = [u8; 0];
4344

45+
#[cfg(feature = "unstable_extern_types")]
46+
extern {
47+
type PrivateMarker;
48+
}
49+
4450
/// A type that represents an instance variable.
4551
#[repr(C)]
4652
pub struct Ivar {

0 commit comments

Comments
 (0)