Skip to content

Commit

Permalink
Make Retained::into_super an inherent method
Browse files Browse the repository at this point in the history
Instead of an associated method
  • Loading branch information
madsmtm committed Sep 19, 2024
1 parent e669d0e commit b94961a
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 13 deletions.
2 changes: 2 additions & 0 deletions crates/objc2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Implemented `PartialEq` and `PartialOrd` on `Retained` in a slightly more
generic way.
* Allow using `Into` to convert to retained objects.
* Make `Retained::into_super` an inherent method instead of an associated
method. This means that you can now use it as `.into_super()`.

### Changed
* **BREAKING**: Changed how you specify a class to only be available on the
Expand Down
2 changes: 1 addition & 1 deletion crates/objc2/examples/class_with_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn main() {
// It is not possible to convert to `Retained<NSObject>`, since that would
// loose the lifetime information that `MyObject` stores.
//
// let obj = Retained::into_super(obj);
// let obj = obj.into_super();
//
// Neither is it not possible to access `number` any more, since `obj`
// holds a mutable reference to it.
Expand Down
15 changes: 11 additions & 4 deletions crates/objc2/src/rc/retained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ use crate::{ffi, ClassType, DowncastTarget, Message};
/// let another_ref: Retained<NSString> = string.clone();
///
/// // Convert one of the references to a reference to `NSObject` instead
/// let obj: Retained<NSObject> = Retained::into_super(string);
/// let obj: Retained<NSObject> = string.into_super();
///
/// // And use the `Debug` impl from that
/// assert_eq!(format!("{obj:?}"), "");
Expand Down Expand Up @@ -355,6 +355,9 @@ impl<T: Message> Retained<T> {
/// All `'static` objects can safely be cast to [`AnyObject`], since that
/// assumes no specific class.
///
/// This is an associated method, and must be called as
/// `Retained::cast_unchecked(obj)`.
///
/// [`AnyObject`]: crate::runtime::AnyObject
/// [`ProtocolObject::from_retained`]: crate::runtime::ProtocolObject::from_retained
/// [`downcast`]: Self::downcast
Expand Down Expand Up @@ -696,14 +699,18 @@ where
T::Super: 'static,
{
/// Convert the object into its superclass.
//
// NOTE: This is _not_ an associated method, since we want it to be easy
// to call, and it it unlikely to conflict with anything (the reference
// version is called `ClassType::as_super`).
#[inline]
pub fn into_super(this: Self) -> Retained<T::Super> {
pub fn into_super(self) -> Retained<T::Super> {
// SAFETY:
// - The casted-to type is a superclass of the type.
// - Both types are `'static`, so no lifetime information is lost
// (this could maybe be relaxed a bit, but let's be on the safe side
// for now).
unsafe { Self::cast_unchecked::<T::Super>(this) }
unsafe { Self::cast_unchecked::<T::Super>(self) }
}
}

Expand Down Expand Up @@ -935,7 +942,7 @@ mod tests {
assert_eq!(cloned.retainCount(), 2);
assert_eq!(obj.retainCount(), 2);

let obj = Retained::into_super(Retained::into_super(obj));
let obj = obj.into_super().into_super();
let cloned_and_type_erased = obj.clone();
expected.retain += 1;
expected.assert_current();
Expand Down
2 changes: 1 addition & 1 deletion crates/objc2/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ impl AnyObject {
/// use objc2::rc::Retained;
/// use objc2_foundation::{NSObject, NSString};
///
/// let obj: Retained<NSObject> = Retained::into_super(NSString::new());
/// let obj: Retained<NSObject> = NSString::new().into_super();
/// let string = obj.downcast_ref::<NSString>().unwrap();
/// // Or with `downcast`, if we do not need the object afterwards
/// let string = obj.downcast::<NSString>().unwrap();
Expand Down
6 changes: 3 additions & 3 deletions crates/objc2/src/topics/about_generated/deref.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ the first place, the problems stated there are less severe, and having the
implementation just means that everything is much nicer when you actually
want to use the objects!

All objects also implement [`AsRef`] and [`AsMut`] to their superclass,
and can be used in [`Retained::into_super`], so if you favour explicit
conversion, that is a possibility too.
All objects also implement [`AsRef`] to their superclass, and can be used in
[`Retained::into_super`], so if you favour explicit conversion, that is a
possibility too.

[`Deref`]: std::ops::Deref
[`ClassType`]: crate::ClassType
Expand Down
4 changes: 2 additions & 2 deletions crates/tests/src/test_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ fn downcast_basics() {
let obj = NSString::new();
assert!(matches!(obj.downcast_ref::<NSString>(), Some(_)));

let obj = Retained::into_super(obj);
let obj = obj.into_super();
assert!(matches!(obj.downcast_ref::<NSNumber>(), None));
assert!(matches!(obj.downcast_ref::<NSString>(), Some(_)));

Expand All @@ -363,7 +363,7 @@ fn downcast_basics() {
assert!(matches!(obj.downcast_ref::<NSObject>(), Some(_)));
assert!(matches!(obj.downcast_ref::<NSException>(), None));

let obj = Retained::into_super(Retained::into_super(obj));
let obj = obj.into_super().into_super();
assert!(matches!(obj.downcast_ref::<NSMutableString>(), Some(_)));
assert!(matches!(obj.downcast_ref::<NSString>(), Some(_)));
assert!(matches!(obj.downcast_ref::<NSObject>(), Some(_)));
Expand Down
2 changes: 1 addition & 1 deletion framework-crates/objc2-foundation/src/tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ fn test_trait_retainable() {

#[test]
fn test_access_anyobject() {
let obj: Retained<AnyObject> = Retained::into_super(NSObject::new());
let obj: Retained<AnyObject> = NSObject::new().into_super();
let array = NSArray::from_retained_slice(&[obj.clone(), obj.clone()]);
assert!(ptr::eq(&*array.objectAtIndex(0), &*obj));
assert!(ptr::eq(unsafe { array.objectAtIndex_unchecked(0) }, &*obj));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn test_debug() {
};
assert_eq!(format!("{s:?}"), expected);

let obj = Retained::into_super(NSObject::new());
let obj = NSObject::new().into_super();
let ptr: *const AnyObject = &*obj;
let s = unsafe {
NSAttributedString::new_with_attributes(
Expand Down

0 comments on commit b94961a

Please sign in to comment.