Skip to content

Commit bb1ae6f

Browse files
committed
Add unstable-coerce-pointee Cargo feature
To experiment with the unstable #[derive(CoercePointee)].
1 parent 4c116d3 commit bb1ae6f

File tree

10 files changed

+61
-1
lines changed

10 files changed

+61
-1
lines changed

crates/block2/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ unstable-objfw = []
4747
# Expose private ffi functions and statics.
4848
unstable-private = []
4949

50+
# Uses the nightly derive_coerce_pointee feature to make conversions more ergonomic.
51+
unstable-coerce-pointee = []
52+
5053
[dependencies]
5154
objc2 = { path = "../objc2", version = "0.5.2", default-features = false, features = ["std"] }
5255

crates/block2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
#![doc(html_root_url = "https://docs.rs/block2/0.5.1")]
304304
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide))]
305305
#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
306+
#![cfg_attr(feature = "unstable-coerce-pointee", feature(derive_coerce_pointee))]
306307

307308
#[cfg(not(feature = "alloc"))]
308309
compile_error!("The `alloc` feature currently must be enabled.");

crates/block2/src/rc_block.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ use crate::{ffi, Block, IntoBlock, StackBlock};
3131
/// `RcBlock<A, R>`.
3232
#[repr(transparent)]
3333
#[doc(alias = "MallocBlock")]
34+
#[cfg_attr(
35+
feature = "unstable-coerce-pointee",
36+
derive(std::marker::CoercePointee)
37+
)]
3438
pub struct RcBlock<F: ?Sized> {
3539
// Covariant
3640
ptr: NonNull<Block<F>>,

crates/objc2/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ unstable-apple-new = []
8989
# ergonomic.
9090
unstable-arbitrary-self-types = []
9191

92+
# Uses the nightly derive_coerce_pointee feature to make conversions more ergonomic.
93+
unstable-coerce-pointee = []
94+
9295
# Deprecated; this is the default on Apple platforms, and not applicable on other platforms.
9396
apple = []
9497

crates/objc2/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@
153153
feature = "unstable-arbitrary-self-types",
154154
feature(arbitrary_self_types)
155155
)]
156+
#![cfg_attr(
157+
feature = "unstable-coerce-pointee",
158+
feature(derive_coerce_pointee, trait_upcasting)
159+
)]
156160
// Note: `doc_notable_trait` doesn't really make sense for us, it's only shown
157161
// for functions returning a specific trait.
158162
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))]

crates/objc2/src/rc/allocated_partial_init.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ use crate::{DefinedClass, Message};
3535
/// object, `*const T`. The pointer may be NULL.
3636
#[repr(transparent)]
3737
#[derive(Debug)]
38+
#[cfg_attr(
39+
feature = "unstable-coerce-pointee",
40+
derive(std::marker::CoercePointee)
41+
)]
3842
pub struct Allocated<T: ?Sized> {
3943
/// The yet-to-be initialized object.
4044
///

crates/objc2/src/rc/retained.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ use crate::{ffi, ClassType, DowncastTarget, Message};
121121
#[doc(alias = "id")]
122122
#[doc(alias = "Id")]
123123
#[doc(alias = "StrongPtr")]
124+
#[cfg_attr(
125+
feature = "unstable-coerce-pointee",
126+
derive(std::marker::CoercePointee)
127+
)]
124128
// TODO: Add `ptr::Thin` bound on `T` to allow for only extern types
125129
pub struct Retained<T: ?Sized> {
126130
/// A pointer to the contained object. The pointer is always retained.
@@ -1014,4 +1018,35 @@ mod tests {
10141018
let _: Retained<NSObject> = Into::into(obj_retained_ref);
10151019
let _: Retained<AnyObject> = Into::into(obj_retained_ref);
10161020
}
1021+
1022+
#[test]
1023+
#[cfg(feature = "unstable-coerce-pointee")]
1024+
fn test_coercion() {
1025+
use crate::{extern_protocol, ProtocolType};
1026+
1027+
extern_protocol!(
1028+
unsafe trait ExampleProtocol: NSObjectProtocol {}
1029+
1030+
unsafe impl ProtocolType for dyn ExampleProtocol {}
1031+
);
1032+
1033+
unsafe impl ExampleProtocol for RcTestObject {}
1034+
1035+
let obj = RcTestObject::new();
1036+
let mut expected = ThreadTestData::current();
1037+
1038+
let obj: Retained<dyn ExampleProtocol> = obj;
1039+
expected.assert_current();
1040+
1041+
let obj: Retained<dyn NSObjectProtocol> = obj;
1042+
expected.assert_current();
1043+
1044+
// TODO: Allow calling methods on trait objects like this.
1045+
// let _ = obj.hash();
1046+
1047+
drop(obj);
1048+
expected.release += 1;
1049+
expected.drop += 1;
1050+
expected.assert_current();
1051+
}
10171052
}

crates/objc2/src/rc/test_object.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::cell::RefCell;
33
use core::ptr;
44

55
use crate::rc::{Allocated, DefaultRetained, Retained};
6-
use crate::runtime::{NSObject, NSZone};
6+
use crate::runtime::{NSObject, NSObjectProtocol, NSZone};
77
use crate::{define_class, msg_send, msg_send_id, ClassType};
88

99
// TODO: Put tests that use this in another crate
@@ -282,6 +282,8 @@ define_class!(
282282
}
283283
}
284284
}
285+
286+
unsafe impl NSObjectProtocol for RcTestObject {}
285287
);
286288

287289
impl Drop for RcTestObject {

crates/objc2/src/rc/weak.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::{ffi, Message};
2929
/// [`sync::Arc`]: std::sync::Arc
3030
#[repr(transparent)] // This is not a public guarantee
3131
#[doc(alias = "WeakId")]
32+
// TODO: Add derive(CoercePointee) once this doesn't Box internally.
3233
pub struct Weak<T: ?Sized> {
3334
/// We give the runtime the address to this box, so that it can modify it
3435
/// even if the `Weak` is moved.

crates/objc2/src/runtime/nsobject.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ pub struct NSObject {
2626
__superclass: AnyObject,
2727
}
2828

29+
// Would be _super_ nice to have this kind of impl, but that isn't possible.
30+
// impl Unsize<AnyObject> for NSObject {}
31+
2932
crate::__extern_class_impl_traits! {
3033
()
3134
(unsafe impl)

0 commit comments

Comments
 (0)