diff --git a/crates/header-translator/src/rust_type.rs b/crates/header-translator/src/rust_type.rs index 6099052d2..a5243e0b7 100644 --- a/crates/header-translator/src/rust_type.rs +++ b/crates/header-translator/src/rust_type.rs @@ -186,12 +186,10 @@ enum IdType { } impl IdType { - #[allow(dead_code)] fn _id(&self) -> Option<&ItemIdentifier> { match self { Self::Class { id, .. } => Some(id), Self::AnyObject { protocols } => match &**protocols { - [id] if id.name == "NSCopying" || id.name == "NSMutableCopying" => None, [id] => Some(id), _ => None, }, @@ -370,9 +368,6 @@ impl fmt::Display for IdType { Self::AnyObject { protocols } => match &**protocols { [] => write!(f, "AnyObject"), [id] if id.is_nsobject() => write!(f, "NSObject"), - [id] if id.name == "NSCopying" || id.name == "NSMutableCopying" => { - write!(f, "AnyObject") - } [id] => write!(f, "ProtocolObject", id.path()), // TODO: Handle this better _ => write!(f, "TodoProtocols"), diff --git a/crates/header-translator/src/stmt.rs b/crates/header-translator/src/stmt.rs index 0413fa514..725cdb5c6 100644 --- a/crates/header-translator/src/stmt.rs +++ b/crates/header-translator/src/stmt.rs @@ -1680,13 +1680,7 @@ impl fmt::Display for Stmt { write!(f, " pub unsafe trait {}", id.name)?; if !protocols.is_empty() { - for (i, protocol) in protocols - .iter() - .filter(|protocol| { - protocol.name != "NSCopying" && protocol.name != "NSMutableCopying" - }) - .enumerate() - { + for (i, protocol) in protocols.iter().enumerate() { if i == 0 { write!(f, ": ")?; } else { diff --git a/crates/icrate/CHANGELOG.md b/crates/icrate/CHANGELOG.md index ca1d11a9c..58593e421 100644 --- a/crates/icrate/CHANGELOG.md +++ b/crates/icrate/CHANGELOG.md @@ -71,6 +71,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). `NSTextAttachmentCellProtocol` and `NSFileProviderItemProtocol`. * **BREAKING**: Generic types no longer strictly require `Message` (although most of their trait implementations still require that). +* **BREAKING**: Removed a workaround that made the `NSCopying` and + `NSMutableCopying` protocols not act as regular protocols (many methods used + `AnyObject` instead of the correct `ProtocolObject`). ## icrate 0.0.4 - 2023-07-31 diff --git a/crates/icrate/src/additions/Foundation/dictionary.rs b/crates/icrate/src/additions/Foundation/dictionary.rs index 2feac65af..411c49d24 100644 --- a/crates/icrate/src/additions/Foundation/dictionary.rs +++ b/crates/icrate/src/additions/Foundation/dictionary.rs @@ -19,6 +19,17 @@ use crate::common::*; use crate::Foundation::NSMutableDictionary; use crate::Foundation::{self, NSCopying, NSDictionary}; +fn keys_to_ptr(keys: &[&Q]) -> *mut NonNull> +where + Q: Message + NSCopying, +{ + let keys: *mut NonNull = util::ref_ptr_cast_const(keys.as_ptr()); + // SAFETY: `Q` is `Message + NSCopying`, and is therefore safe to cast to + // `ProtocolObject`. + let keys: *mut NonNull> = keys.cast(); + keys +} + impl NSDictionary { pub fn from_vec(keys: &[&Q], mut objects: Vec>) -> Id where @@ -31,8 +42,7 @@ impl NSDictionary { // different lengths, either would be fine. let count = min(keys.len(), objects.len()); - let keys: *mut NonNull = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys = keys_to_ptr(keys); let objects = util::id_ptr_cast(objects.as_mut_ptr()); // SAFETY: @@ -62,8 +72,7 @@ impl NSDictionary { { let count = min(keys.len(), objects.len()); - let keys: *mut NonNull = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys = keys_to_ptr(keys); let objects = util::id_ptr_cast_const(objects.as_ptr()); // SAFETY: See `NSDictionary::from_vec` and `NSArray::from_id_slice`. @@ -77,8 +86,7 @@ impl NSDictionary { { let count = min(keys.len(), objects.len()); - let keys: *mut NonNull = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys = keys_to_ptr(keys); let objects = util::ref_ptr_cast_const(objects.as_ptr()); // SAFETY: See `NSDictionary::from_vec` and `NSArray::from_slice`. @@ -95,7 +103,7 @@ impl NSMutableDictionary = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys: *mut NonNull> = keys.cast(); let objects = util::id_ptr_cast(objects.as_mut_ptr()); // SAFETY: See `NSDictionary::from_vec` @@ -109,8 +117,7 @@ impl NSMutableDictionary = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys = keys_to_ptr(keys); let objects = util::id_ptr_cast_const(objects.as_ptr()); // SAFETY: See `NSDictionary::from_vec` and `NSArray::from_id_slice`. @@ -124,8 +131,7 @@ impl NSMutableDictionary = util::ref_ptr_cast_const(keys.as_ptr()); - let keys: *mut NonNull = keys.cast(); + let keys = keys_to_ptr(keys); let objects = util::ref_ptr_cast_const(objects.as_ptr()); // SAFETY: See `NSDictionary::from_vec` and `NSArray::from_slice`. @@ -335,13 +341,8 @@ impl NSMutableDictionary = NonNull::from(key); - let key: NonNull = key.cast(); - let key: &AnyObject = unsafe { key.as_ref() }; - // SAFETY: The key is NSCopying (see `NSDictionary::from_vec`), and we - // have ownership over the value. + let key = ProtocolObject::from_ref(key); + // SAFETY: We have ownership over the value. unsafe { self.setObject_forKey(&value, key) }; old_obj } @@ -371,14 +372,9 @@ impl NSMutableDictionary = NonNull::from(key); - let key: NonNull = key.cast(); - let key: &AnyObject = unsafe { key.as_ref() }; - // SAFETY: The key is NSCopying (see `NSDictionary::from_vec`), and - // the value is `IsRetainable` (and hence safe for the collection to - // retain). + let key = ProtocolObject::from_ref(key); + // SAFETY: The value is `IsRetainable`, and hence safe for the + // collection to retain. unsafe { self.setObject_forKey(value, key) }; old_obj } diff --git a/crates/icrate/src/generated b/crates/icrate/src/generated index 6f3a2cf19..ea169f942 160000 --- a/crates/icrate/src/generated +++ b/crates/icrate/src/generated @@ -1 +1 @@ -Subproject commit 6f3a2cf19589d89bd9c6bbe7e99186a6a45640b6 +Subproject commit ea169f942ef758aacbdd073883d578ebb59389c5