Skip to content

Commit 889e6ba

Browse files
committed
Relax Sized bound on Id's retain and autorelease
1 parent 9f4f50f commit 889e6ba

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

objc2/src/rc/id.rs

+22-17
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,7 @@ impl<T: Message + ?Sized, O: Ownership> Id<T, O> {
173173
own: PhantomData,
174174
}
175175
}
176-
}
177176

178-
// TODO: Add ?Sized bound
179-
impl<T: Message, O: Ownership> Id<T, O> {
180177
/// Retains the given object pointer.
181178
///
182179
/// This is useful when you have been given a pointer to an object from
@@ -212,14 +209,20 @@ impl<T: Message, O: Ownership> Id<T, O> {
212209
#[doc(alias = "objc_retain")]
213210
#[cfg_attr(not(debug_assertions), inline)]
214211
pub unsafe fn retain(ptr: NonNull<T>) -> Id<T, O> {
215-
let ptr = ptr.as_ptr() as *mut ffi::objc_object;
212+
let ptr = ptr.as_ptr();
213+
let obj_ptr = ptr as *mut ffi::objc_object;
216214
// SAFETY: The caller upholds that the pointer is valid
217-
let res = unsafe { ffi::objc_retain(ptr) };
218-
debug_assert_eq!(res, ptr, "objc_retain did not return the same pointer");
215+
let res = unsafe { ffi::objc_retain(obj_ptr) };
216+
debug_assert_eq!(res, obj_ptr, "objc_retain did not return the same pointer");
219217
// SAFETY: Non-null upheld by the caller, and `objc_retain` always
220218
// returns the same pointer, see:
221219
// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain
222-
let res = unsafe { NonNull::new_unchecked(res as *mut T) };
220+
//
221+
// TODO: Use `res` instead, in the odd case where `objc_retain` did
222+
// not return the same pointer. We can't do this currently because we
223+
// have a ?Sized bound on T to support extern types, which means we
224+
// can go from `*mut T` to `*mut objc_object`, but not the other way.
225+
let res = unsafe { NonNull::new_unchecked(ptr) };
223226
// SAFETY: We just retained the object, so it has +1 retain count
224227
unsafe { Self::new(res) }
225228
}
@@ -232,14 +235,19 @@ impl<T: Message, O: Ownership> Id<T, O> {
232235
// retained objects it is hard to imagine a case where the inner type
233236
// has a method with the same name.
234237

235-
let ptr = ManuallyDrop::new(self).ptr.as_ptr() as *mut ffi::objc_object;
238+
let ptr = ManuallyDrop::new(self).ptr.as_ptr();
239+
let obj_ptr = ptr as *mut ffi::objc_object;
236240
// SAFETY: The `ptr` is guaranteed to be valid and have at least one
237241
// retain count.
238242
// And because of the ManuallyDrop, we don't call the Drop
239243
// implementation, so the object won't also be released there.
240-
let res = unsafe { ffi::objc_autorelease(ptr) };
241-
debug_assert_eq!(res, ptr, "objc_autorelease did not return the same pointer");
242-
res as *mut T
244+
let res = unsafe { ffi::objc_autorelease(obj_ptr) };
245+
debug_assert_eq!(
246+
res, obj_ptr,
247+
"objc_autorelease did not return the same pointer"
248+
);
249+
// TODO: Return `res`, see explanation in `retain`.
250+
ptr
243251
}
244252

245253
// TODO: objc_retainAutoreleasedReturnValue
@@ -259,8 +267,7 @@ impl<T: Message, O: Ownership> Id<T, O> {
259267
// }
260268
// }
261269

262-
// TODO: Add ?Sized bound
263-
impl<T: Message> Id<T, Owned> {
270+
impl<T: Message + ?Sized> Id<T, Owned> {
264271
/// Autoreleases the owned [`Id`], returning a mutable reference bound to
265272
/// the pool.
266273
///
@@ -297,8 +304,7 @@ impl<T: Message> Id<T, Owned> {
297304
}
298305
}
299306

300-
// TODO: Add ?Sized bound
301-
impl<T: Message> Id<T, Shared> {
307+
impl<T: Message + ?Sized> Id<T, Shared> {
302308
/// Autoreleases the shared [`Id`], returning an aliased reference bound
303309
/// to the pool.
304310
///
@@ -325,8 +331,7 @@ impl<T: Message + ?Sized> From<Id<T, Owned>> for Id<T, Shared> {
325331
}
326332
}
327333

328-
// TODO: Add ?Sized bound
329-
impl<T: Message> Clone for Id<T, Shared> {
334+
impl<T: Message + ?Sized> Clone for Id<T, Shared> {
330335
/// Makes a clone of the shared object.
331336
///
332337
/// This increases the object's reference count.

0 commit comments

Comments
 (0)