Skip to content

Commit 7a94811

Browse files
committed
Consume ManuallyDrop<Id<T, O>> in msg_send!
If you do not want to consume it, the possibility of doing `msg_send![&*obj]` exists, but most of the time that is indeed what you want (I mean, why else would you wrap it in `ManuallyDrop`?)
1 parent d9a328e commit 7a94811

File tree

4 files changed

+29
-36
lines changed

4 files changed

+29
-36
lines changed

objc2/src/message/mod.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ pub(crate) mod private {
8383
impl<'a, T: Message + ?Sized, O: Ownership> Sealed for &'a Id<T, O> {}
8484
impl<'a, T: Message + ?Sized> Sealed for &'a mut Id<T, Owned> {}
8585

86-
impl<'a, T: Message + ?Sized, O: Ownership> Sealed for &'a ManuallyDrop<Id<T, O>> {}
87-
impl<'a, T: Message + ?Sized> Sealed for &'a mut ManuallyDrop<Id<T, Owned>> {}
86+
impl<T: Message + ?Sized, O: Ownership> Sealed for ManuallyDrop<Id<T, O>> {}
8887
}
8988

9089
/// Types that can directly be used as the receiver of Objective-C messages.
@@ -267,17 +266,10 @@ unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut Id<T, Owned> {
267266
}
268267
}
269268

270-
unsafe impl<'a, T: Message + ?Sized, O: Ownership> MessageReceiver for &'a ManuallyDrop<Id<T, O>> {
269+
unsafe impl<T: Message + ?Sized, O: Ownership> MessageReceiver for ManuallyDrop<Id<T, O>> {
271270
#[inline]
272271
fn as_raw_receiver(self) -> *mut Object {
273-
Id::as_ptr(&**self) as *mut Object
274-
}
275-
}
276-
277-
unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut ManuallyDrop<Id<T, Owned>> {
278-
#[inline]
279-
fn as_raw_receiver(self) -> *mut Object {
280-
Id::as_mut_ptr(&mut **self) as *mut Object
272+
Id::consume_as_ptr(self) as *mut Object
281273
}
282274
}
283275

@@ -481,17 +473,11 @@ mod tests {
481473

482474
#[test]
483475
fn test_send_message_manuallydrop() {
484-
let obj = test_utils::custom_object();
485-
let mut obj = ManuallyDrop::new(obj);
486-
let result: u32 = unsafe {
487-
let _: () = msg_send![&mut obj, setFoo: 4u32];
488-
msg_send![&obj, foo]
476+
let obj = ManuallyDrop::new(test_utils::custom_object());
477+
unsafe {
478+
let _: () = msg_send![obj, release];
489479
};
490-
assert_eq!(result, 4);
491-
492-
let obj: *const ManuallyDrop<Object> = obj.as_ptr().cast();
493-
let result: u32 = unsafe { msg_send![obj, foo] };
494-
assert_eq!(result, 4);
480+
// `obj` is consumed, can't use here
495481
}
496482

497483
#[test]

objc2/src/rc/id.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ impl<T: Message + ?Sized, O: Ownership> Id<T, O> {
199199
pub fn as_ptr(this: &Id<T, O>) -> *const T {
200200
this.ptr.as_ptr()
201201
}
202+
203+
#[inline]
204+
pub(crate) fn consume_as_ptr(this: ManuallyDrop<Self>) -> *mut T {
205+
this.ptr.as_ptr()
206+
}
202207
}
203208

204209
impl<T: Message + ?Sized> Id<T, Owned> {

objc2/src/test_utils.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,26 @@ impl CustomObject {
2323
// TODO: Remove the need for this hack
2424
impl crate::message::private::Sealed for &CustomObject {}
2525
impl crate::message::private::Sealed for &mut CustomObject {}
26-
impl crate::message::private::Sealed for &ManuallyDrop<CustomObject> {}
27-
impl crate::message::private::Sealed for &mut ManuallyDrop<CustomObject> {}
26+
impl crate::message::private::Sealed for ManuallyDrop<CustomObject> {}
2827

2928
unsafe impl MessageReceiver for &CustomObject {
3029
#[inline]
3130
fn as_raw_receiver(self) -> *mut Object {
32-
(&**self).as_raw_receiver()
31+
self.obj
3332
}
3433
}
3534

3635
unsafe impl MessageReceiver for &mut CustomObject {
3736
#[inline]
3837
fn as_raw_receiver(self) -> *mut Object {
39-
(&**self).as_raw_receiver()
38+
self.obj
4039
}
4140
}
4241

43-
unsafe impl MessageReceiver for &ManuallyDrop<CustomObject> {
42+
unsafe impl MessageReceiver for ManuallyDrop<CustomObject> {
4443
#[inline]
4544
fn as_raw_receiver(self) -> *mut Object {
46-
(&**self).as_raw_receiver()
47-
}
48-
}
49-
50-
unsafe impl MessageReceiver for &mut ManuallyDrop<CustomObject> {
51-
#[inline]
52-
fn as_raw_receiver(self) -> *mut Object {
53-
(&**self).as_raw_receiver()
45+
self.obj
5446
}
5547
}
5648

@@ -106,6 +98,14 @@ pub(crate) fn custom_class() -> &'static Class {
10698
builder.add_protocol(proto);
10799
builder.add_ivar::<u32>("_foo");
108100

101+
unsafe extern "C" fn custom_obj_release(
102+
this: *mut Object,
103+
_cmd: Sel,
104+
) {
105+
// Drop the value
106+
let _ = CustomObject { obj: this };
107+
}
108+
109109
extern "C" fn custom_obj_set_foo(this: &mut Object, _cmd: Sel, foo: u32) {
110110
unsafe {
111111
this.set_ivar::<u32>("_foo", foo);
@@ -145,6 +145,9 @@ pub(crate) fn custom_class() -> &'static Class {
145145
}
146146

147147
unsafe {
148+
let release: unsafe extern "C" fn(*mut Object, Sel) = custom_obj_release;
149+
builder.add_method(sel!(release), release);
150+
148151
let set_foo: extern "C" fn(&mut Object, Sel, u32) = custom_obj_set_foo;
149152
builder.add_method(sel!(setFoo:), set_foo);
150153
let get_foo: extern "C" fn(&Object, Sel) -> u32 = custom_obj_get_foo;

tests/ui/msg_send_only_message.stderr

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ error[E0277]: the trait bound `{integer}: MessageReceiver` is not satisfied
66
|
77
= help: the following other types implement trait `MessageReceiver`:
88
&'a Id<T, O>
9-
&'a ManuallyDrop<Id<T, O>>
109
&'a T
1110
&'a mut Id<T, objc2::rc::Owned>
12-
&'a mut ManuallyDrop<Id<T, objc2::rc::Owned>>
1311
&'a mut T
1412
*const T
1513
*mut T
14+
ManuallyDrop<Id<T, O>>
1615
NonNull<T>
1716
= note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)