Skip to content

Commit 195508e

Browse files
authored
Merge pull request #159 from madsmtm/future-proof-traits
Future proof `MessageReceiver` and `MethodImplementation` traits
2 parents 42b847a + 8c5d3ff commit 195508e

File tree

4 files changed

+58
-34
lines changed

4 files changed

+58
-34
lines changed

objc2/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6161
* **BREAKING**: `Class` no longer implements `Message` (but it can still be
6262
used as the receiver in `msg_send!`, so this is unlikely to break anything
6363
in practice).
64+
* **BREAKING**: Sealed the `MethodImplementation` trait, and made it's `imp`
65+
method privat.
6466

6567
### Fixed
6668
* Properly sealed the `MessageArguments` trait (it already had a hidden
6769
method, so this is not really a breaking change).
6870

6971
### Removed
7072
* **BREAKING**: `ManuallyDrop` no longer implements `Message` directly.
73+
* **BREAKING**: `MessageReceiver::as_raw_receiver` is no longer public.
7174

7275

7376
## 0.3.0-alpha.6 - 2022-01-03

objc2/src/declare.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,37 @@ use core::ptr::NonNull;
4343
use std::ffi::CString;
4444

4545
use crate::runtime::{Bool, Class, Imp, Object, Protocol, Sel};
46-
use crate::{ffi, Encode, EncodeArguments, Encoding, Message};
46+
use crate::{ffi, Encode, EncodeArguments, Encoding, Message, RefEncode};
47+
48+
pub(crate) mod private {
49+
pub trait Sealed {}
50+
}
4751

4852
/// Types that can be used as the implementation of an Objective-C method.
49-
pub trait MethodImplementation {
53+
///
54+
/// This is a sealed trait that is implemented for a lot of `extern "C"`
55+
/// function pointer types.
56+
pub trait MethodImplementation: private::Sealed {
5057
/// The callee type of the method.
51-
type Callee: ?Sized;
58+
type Callee: RefEncode + ?Sized;
5259
/// The return type of the method.
5360
type Ret: Encode;
5461
/// The argument types of the method.
5562
type Args: EncodeArguments;
5663

57-
/// Returns self as an [`Imp`] of a method.
58-
fn imp(self) -> Imp;
64+
#[doc(hidden)]
65+
fn __imp(self) -> Imp;
5966
}
6067

6168
macro_rules! method_decl_impl {
62-
(-$s:ident, $r:ident, $f:ty, $($t:ident),*) => (
69+
(-$s:ident, $r:ident, $f:ty, $($t:ident),*) => {
70+
impl<$s, $r, $($t),*> private::Sealed for $f
71+
where
72+
$s: Message + ?Sized,
73+
$r: Encode,
74+
$($t: Encode,)*
75+
{}
76+
6377
impl<$s, $r, $($t),*> MethodImplementation for $f
6478
where
6579
$s: Message + ?Sized,
@@ -70,12 +84,18 @@ macro_rules! method_decl_impl {
7084
type Ret = $r;
7185
type Args = ($($t,)*);
7286

73-
fn imp(self) -> Imp {
87+
fn __imp(self) -> Imp {
7488
unsafe { mem::transmute(self) }
7589
}
7690
}
77-
);
78-
(@$s:ident, $r:ident, $f:ty, $($t:ident),*) => (
91+
};
92+
(@$s:ident, $r:ident, $f:ty, $($t:ident),*) => {
93+
impl<$r, $($t),*> private::Sealed for $f
94+
where
95+
$r: Encode,
96+
$($t: Encode,)*
97+
{}
98+
7999
impl<$r, $($t),*> MethodImplementation for $f
80100
where
81101
$r: Encode,
@@ -85,12 +105,12 @@ macro_rules! method_decl_impl {
85105
type Ret = $r;
86106
type Args = ($($t,)*);
87107

88-
fn imp(self) -> Imp {
108+
fn __imp(self) -> Imp {
89109
unsafe { mem::transmute(self) }
90110
}
91111
}
92-
);
93-
($($t:ident),*) => (
112+
};
113+
($($t:ident),*) => {
94114
method_decl_impl!(-T, R, extern "C" fn(&T, Sel $(, $t)*) -> R, $($t),*);
95115
method_decl_impl!(-T, R, extern "C" fn(&mut T, Sel $(, $t)*) -> R, $($t),*);
96116
method_decl_impl!(-T, R, unsafe extern "C" fn(*const T, Sel $(, $t)*) -> R, $($t),*);
@@ -101,7 +121,7 @@ macro_rules! method_decl_impl {
101121
method_decl_impl!(@Class, R, extern "C" fn(&Class, Sel $(, $t)*) -> R, $($t),*);
102122
method_decl_impl!(@Class, R, unsafe extern "C" fn(*const Class, Sel $(, $t)*) -> R, $($t),*);
103123
method_decl_impl!(@Class, R, unsafe extern "C" fn(&Class, Sel $(, $t)*) -> R, $($t),*);
104-
);
124+
};
105125
}
106126

107127
method_decl_impl!();
@@ -237,7 +257,7 @@ impl ClassBuilder {
237257
ffi::class_addMethod(
238258
self.as_ptr(),
239259
sel.as_ptr() as _,
240-
Some(func.imp()),
260+
Some(func.__imp()),
241261
types.as_ptr(),
242262
)
243263
});
@@ -275,7 +295,7 @@ impl ClassBuilder {
275295
ffi::class_addMethod(
276296
metaclass,
277297
sel.as_ptr() as _,
278-
Some(func.imp()),
298+
Some(func.__imp()),
279299
types.as_ptr(),
280300
)
281301
});

objc2/src/message/mod.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,11 @@ pub(crate) mod private {
9898
///
9999
/// # Safety
100100
///
101-
/// [`Self::as_raw_receiver`] must be implemented correctly.
101+
/// This is a sealed trait, and should not need to be implemented. Open an
102+
/// issue if you know a use-case where this restrition should be lifted!
102103
pub unsafe trait MessageReceiver: private::Sealed + Sized {
103-
/// Get a raw pointer to the receiver of the message.
104-
fn as_raw_receiver(self) -> *mut Object;
104+
#[doc(hidden)]
105+
fn __as_raw_receiver(self) -> *mut Object;
105106

106107
/// Sends a message to self with the given selector and arguments.
107108
///
@@ -126,7 +127,7 @@ pub unsafe trait MessageReceiver: private::Sealed + Sized {
126127
A: MessageArguments,
127128
R: Encode,
128129
{
129-
let this = self.as_raw_receiver();
130+
let this = self.__as_raw_receiver();
130131
// TODO: Always enable this when `debug_assertions` are on.
131132
#[cfg(feature = "verify_message")]
132133
{
@@ -173,7 +174,7 @@ pub unsafe trait MessageReceiver: private::Sealed + Sized {
173174
A: MessageArguments,
174175
R: Encode,
175176
{
176-
let this = self.as_raw_receiver();
177+
let this = self.__as_raw_receiver();
177178
#[cfg(feature = "verify_message")]
178179
{
179180
if this.is_null() {
@@ -210,7 +211,7 @@ pub unsafe trait MessageReceiver: private::Sealed + Sized {
210211
A: EncodeArguments,
211212
R: Encode,
212213
{
213-
let obj = unsafe { &*self.as_raw_receiver() };
214+
let obj = unsafe { &*self.__as_raw_receiver() };
214215
verify_message_signature::<A, R>(obj.class(), sel).map_err(MessageError::from)
215216
}
216217
}
@@ -220,70 +221,70 @@ pub unsafe trait MessageReceiver: private::Sealed + Sized {
220221

221222
unsafe impl<T: Message + ?Sized> MessageReceiver for *const T {
222223
#[inline]
223-
fn as_raw_receiver(self) -> *mut Object {
224+
fn __as_raw_receiver(self) -> *mut Object {
224225
self as *mut T as *mut Object
225226
}
226227
}
227228

228229
unsafe impl<T: Message + ?Sized> MessageReceiver for *mut T {
229230
#[inline]
230-
fn as_raw_receiver(self) -> *mut Object {
231+
fn __as_raw_receiver(self) -> *mut Object {
231232
self as *mut Object
232233
}
233234
}
234235

235236
unsafe impl<T: Message + ?Sized> MessageReceiver for NonNull<T> {
236237
#[inline]
237-
fn as_raw_receiver(self) -> *mut Object {
238+
fn __as_raw_receiver(self) -> *mut Object {
238239
self.as_ptr() as *mut Object
239240
}
240241
}
241242

242243
unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a T {
243244
#[inline]
244-
fn as_raw_receiver(self) -> *mut Object {
245+
fn __as_raw_receiver(self) -> *mut Object {
245246
self as *const T as *mut T as *mut Object
246247
}
247248
}
248249

249250
unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut T {
250251
#[inline]
251-
fn as_raw_receiver(self) -> *mut Object {
252+
fn __as_raw_receiver(self) -> *mut Object {
252253
self as *const T as *mut T as *mut Object
253254
}
254255
}
255256

256257
unsafe impl<'a, T: Message + ?Sized, O: Ownership> MessageReceiver for &'a Id<T, O> {
257258
#[inline]
258-
fn as_raw_receiver(self) -> *mut Object {
259+
fn __as_raw_receiver(self) -> *mut Object {
259260
Id::as_ptr(self) as *mut Object
260261
}
261262
}
262263

263264
unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut Id<T, Owned> {
264265
#[inline]
265-
fn as_raw_receiver(self) -> *mut Object {
266+
fn __as_raw_receiver(self) -> *mut Object {
266267
Id::as_mut_ptr(self) as *mut Object
267268
}
268269
}
269270

270271
unsafe impl<T: Message + ?Sized, O: Ownership> MessageReceiver for ManuallyDrop<Id<T, O>> {
271272
#[inline]
272-
fn as_raw_receiver(self) -> *mut Object {
273+
fn __as_raw_receiver(self) -> *mut Object {
273274
Id::consume_as_ptr(self) as *mut Object
274275
}
275276
}
276277

277278
unsafe impl MessageReceiver for *const Class {
278279
#[inline]
279-
fn as_raw_receiver(self) -> *mut Object {
280+
fn __as_raw_receiver(self) -> *mut Object {
280281
self as *mut Class as *mut Object
281282
}
282283
}
283284

284285
unsafe impl<'a> MessageReceiver for &'a Class {
285286
#[inline]
286-
fn as_raw_receiver(self) -> *mut Object {
287+
fn __as_raw_receiver(self) -> *mut Object {
287288
self as *const Class as *mut Class as *mut Object
288289
}
289290
}

objc2/src/test_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@ impl crate::message::private::Sealed for ManuallyDrop<CustomObject> {}
2727

2828
unsafe impl MessageReceiver for &CustomObject {
2929
#[inline]
30-
fn as_raw_receiver(self) -> *mut Object {
30+
fn __as_raw_receiver(self) -> *mut Object {
3131
self.obj
3232
}
3333
}
3434

3535
unsafe impl MessageReceiver for &mut CustomObject {
3636
#[inline]
37-
fn as_raw_receiver(self) -> *mut Object {
37+
fn __as_raw_receiver(self) -> *mut Object {
3838
self.obj
3939
}
4040
}
4141

4242
unsafe impl MessageReceiver for ManuallyDrop<CustomObject> {
4343
#[inline]
44-
fn as_raw_receiver(self) -> *mut Object {
44+
fn __as_raw_receiver(self) -> *mut Object {
4545
self.obj
4646
}
4747
}

0 commit comments

Comments
 (0)