Skip to content

Commit

Permalink
Make generic types not strictly require T: Message
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Sep 11, 2023
1 parent f4e8eea commit 2f6e76b
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 173 deletions.
26 changes: 14 additions & 12 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ impl fmt::Display for Stmt {
if !generics.is_empty() {
write!(f, "<")?;
for generic in generics {
write!(f, "{generic}: Message = AnyObject, ")?;
write!(f, "{generic}: ?Sized = AnyObject, ")?;
}
write!(f, ">")?;
};
Expand Down Expand Up @@ -1411,7 +1411,7 @@ impl fmt::Display for Stmt {
writeln!(
f,
" unsafe impl{} ClassType for {}{} {{",
GenericParamsHelper(generics, "Message"),
GenericParamsHelper(generics, "?Sized + Message"),
id.name,
GenericTyHelper(generics),
)?;
Expand Down Expand Up @@ -1494,6 +1494,7 @@ impl fmt::Display for Stmt {
if let Some(feature) = cls.feature() {
writeln!(f, " #[cfg(feature = \"{feature}\")]")?;
}
// TODO: Add ?Sized here once `extern_methods!` supports it.
writeln!(
f,
" unsafe impl{} {}{} {{",
Expand Down Expand Up @@ -1545,6 +1546,7 @@ impl fmt::Display for Stmt {
writeln!(f, ");")?;

if let Some(method) = methods.iter().find(|method| method.usable_in_default_id()) {
writeln!(f)?;
if let Some(feature) = cls.feature() {
// Assume new methods require no extra features
writeln!(f, " #[cfg(feature = \"{feature}\")]")?;
Expand Down Expand Up @@ -1574,11 +1576,11 @@ impl fmt::Display for Stmt {
// The object inherits from `NSObject` or `NSProxy` no
// matter what the generic type is, so this must be
// safe.
(_, _) if protocol.is_nsobject() => ("Message", None),
(_, _) if protocol.is_nsobject() => ("?Sized", None),
// Encoding and decoding requires that the inner types
// are codable as well.
("Foundation", "NSCoding") => ("Message + NSCoding", None),
("Foundation", "NSSecureCoding") => ("Message + NSSecureCoding", None),
("Foundation", "NSCoding") => ("?Sized + NSCoding", None),
("Foundation", "NSSecureCoding") => ("?Sized + NSSecureCoding", None),
// Copying collections is done as a shallow copy:
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html>
//
Expand All @@ -1588,24 +1590,24 @@ impl fmt::Display for Stmt {
//
// The types does have to be cloneable, since generic
// types effectively store an `Id<T>` of the type.
("Foundation", "NSCopying") => ("IsIdCloneable", None),
("Foundation", "NSMutableCopying") => ("IsIdCloneable", None),
("Foundation", "NSCopying") => ("?Sized + IsIdCloneable", None),
("Foundation", "NSMutableCopying") => ("?Sized + IsIdCloneable", None),
// TODO: Do we need further tweaks to this?
("Foundation", "NSFastEnumeration") => ("Message", None),
("Foundation", "NSFastEnumeration") => ("?Sized", None),
// AppKit fixes. TODO: Should we add more bounds here?
("AppKit", "NSCollectionViewDataSource") => ("Message", None),
("AppKit", "NSTableViewDataSource") => ("Message", None),
("AppKit", "NSCollectionViewDataSource") => ("?Sized", None),
("AppKit", "NSTableViewDataSource") => ("?Sized", None),
_ => {
error!(
?protocol,
?cls,
"unknown where bound for generic protocol impl"
);
("Message", None)
("?Sized", None)
}
}
} else {
("Message", None)
("InvalidGenericBound", None)
};

if let Some(feature) = cls.feature() {
Expand Down
2 changes: 2 additions & 0 deletions crates/icrate/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
`NSSet` creation methods, fixing a long-standing soundess issue.
* Fixed the protocol names of `NSAccessibilityElementProtocol`,
`NSTextAttachmentCellProtocol` and `NSFileProviderItemProtocol`.
* **BREAKING**: Generic types no longer strictly require `Message` (although
most of their trait implementations still require that).


## icrate 0.0.4 - 2023-07-31
Expand Down
4 changes: 2 additions & 2 deletions crates/icrate/src/fixes/AppKit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ extern_class!(
__inner_extern_class!(
#[cfg(feature = "AppKit_NSLayoutAnchor")]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NSLayoutAnchor<AnchorType: Message = AnyObject> {
pub struct NSLayoutAnchor<AnchorType: ?Sized = AnyObject> {
__superclass: NSObject,
_inner0: PhantomData<*mut AnchorType>,
notunwindsafe: PhantomData<&'static mut ()>,
}

#[cfg(feature = "AppKit_NSLayoutAnchor")]
unsafe impl<AnchorType: Message> ClassType for NSLayoutAnchor<AnchorType> {
unsafe impl<AnchorType: ?Sized + Message> ClassType for NSLayoutAnchor<AnchorType> {
type Super = NSObject;
type Mutability = InteriorMutable;

Expand Down
8 changes: 8 additions & 0 deletions crates/icrate/src/fixes/Foundation/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ impl<K: fmt::Debug + Message, V: fmt::Debug + Message> fmt::Debug
}
}

#[cfg(feature = "Foundation_NSCountedSet")]
impl<T: fmt::Debug + Message> fmt::Debug for Foundation::NSCountedSet<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}

#[cfg(feature = "Foundation_NSMutableSet")]
impl<T: fmt::Debug + Message> fmt::Debug for Foundation::NSMutableSet<T> {
#[inline]
Expand Down
44 changes: 23 additions & 21 deletions crates/icrate/src/fixes/Foundation/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl<T: ?Sized> UnwindSafe for UnsafeIgnoreAutoTraits<T> {}
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSArray")]
pub struct NSArray<ObjectType: Message = AnyObject> {
pub struct NSArray<ObjectType: ?Sized = AnyObject> {
// SAFETY: Auto traits specified below.
__superclass: UnsafeIgnoreAutoTraits<NSObject>,
/// `NSArray` and `NSMutableArray` have `Id`-like storage.
Expand Down Expand Up @@ -84,7 +84,7 @@ __inner_extern_class!(
}

#[cfg(feature = "Foundation_NSArray")]
unsafe impl<ObjectType: Message> ClassType for NSArray<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSArray<ObjectType> {
type Super = NSObject;
type Mutability = ImmutableWithMutableSubclass<NSMutableArray<ObjectType>>;

Expand All @@ -101,13 +101,13 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSArray")]
pub struct NSMutableArray<ObjectType: Message = AnyObject> {
pub struct NSMutableArray<ObjectType: ?Sized = AnyObject> {
// Inherit auto traits from superclass.
__superclass: NSArray<ObjectType>,
}

#[cfg(feature = "Foundation_NSArray")]
unsafe impl<ObjectType: Message> ClassType for NSMutableArray<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSMutableArray<ObjectType> {
#[inherits(NSObject)]
type Super = NSArray<ObjectType>;
type Mutability = MutableWithImmutableSuperclass<NSArray<ObjectType>>;
Expand All @@ -125,7 +125,7 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSDictionary")]
pub struct NSDictionary<KeyType: Message = AnyObject, ObjectType: Message = AnyObject> {
pub struct NSDictionary<KeyType: ?Sized = AnyObject, ObjectType: ?Sized = AnyObject> {
// SAFETY: Auto traits specified below.
__superclass: UnsafeIgnoreAutoTraits<NSObject>,
// Same as if the dictionary was implemented with:
Expand All @@ -134,7 +134,9 @@ __inner_extern_class!(
}

#[cfg(feature = "Foundation_NSDictionary")]
unsafe impl<KeyType: Message, ObjectType: Message> ClassType for NSDictionary<KeyType, ObjectType> {
unsafe impl<KeyType: ?Sized + Message, ObjectType: ?Sized + Message> ClassType
for NSDictionary<KeyType, ObjectType>
{
type Super = NSObject;
type Mutability = ImmutableWithMutableSubclass<NSMutableDictionary<KeyType, ObjectType>>;

Expand All @@ -151,13 +153,13 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSDictionary")]
pub struct NSMutableDictionary<KeyType: Message = AnyObject, ObjectType: Message = AnyObject> {
pub struct NSMutableDictionary<KeyType: ?Sized = AnyObject, ObjectType: ?Sized = AnyObject> {
// Inherit auto traits from superclass.
__superclass: NSDictionary<KeyType, ObjectType>,
}

#[cfg(feature = "Foundation_NSDictionary")]
unsafe impl<KeyType: Message, ObjectType: Message> ClassType
unsafe impl<KeyType: ?Sized + Message, ObjectType: ?Sized + Message> ClassType
for NSMutableDictionary<KeyType, ObjectType>
{
#[inherits(NSObject)]
Expand All @@ -177,15 +179,15 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSSet")]
pub struct NSSet<ObjectType: Message = AnyObject> {
pub struct NSSet<ObjectType: ?Sized = AnyObject> {
// SAFETY: Auto traits specified below.
__superclass: UnsafeIgnoreAutoTraits<NSObject>,
// Same as if the set was implemented as `NSArray<ObjectType>`.
__inner: PhantomData<Id<ObjectType>>,
}

#[cfg(feature = "Foundation_NSSet")]
unsafe impl<ObjectType: Message> ClassType for NSSet<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSSet<ObjectType> {
type Super = NSObject;
type Mutability = ImmutableWithMutableSubclass<NSMutableSet<ObjectType>>;

Expand All @@ -202,13 +204,13 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSSet")]
pub struct NSMutableSet<ObjectType: Message = AnyObject> {
pub struct NSMutableSet<ObjectType: ?Sized = AnyObject> {
// Inherit auto traits from superclass.
__superclass: NSSet<ObjectType>,
}

#[cfg(feature = "Foundation_NSSet")]
unsafe impl<ObjectType: Message> ClassType for NSMutableSet<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSMutableSet<ObjectType> {
#[inherits(NSObject)]
type Super = NSSet<ObjectType>;
type Mutability = MutableWithImmutableSuperclass<NSSet<ObjectType>>;
Expand All @@ -224,15 +226,15 @@ __inner_extern_class!(
);

__inner_extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)]
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSCountedSet")]
pub struct NSCountedSet<ObjectType: Message = AnyObject> {
pub struct NSCountedSet<ObjectType: ?Sized = AnyObject> {
// Inherit auto traits from superclass.
__superclass: NSMutableSet<ObjectType>,
}

#[cfg(feature = "Foundation_NSCountedSet")]
unsafe impl<ObjectType: Message> ClassType for NSCountedSet<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSCountedSet<ObjectType> {
#[inherits(NSSet<ObjectType>, NSObject)]
type Super = NSMutableSet<ObjectType>;
type Mutability = Mutable;
Expand All @@ -250,15 +252,15 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSOrderedSet")]
pub struct NSOrderedSet<ObjectType: Message = AnyObject> {
pub struct NSOrderedSet<ObjectType: ?Sized = AnyObject> {
// SAFETY: Auto traits specified below.
__superclass: UnsafeIgnoreAutoTraits<NSObject>,
// Same as if the set was implemented with `NSArray<ObjectType>`.
__inner: PhantomData<Id<ObjectType>>,
}

#[cfg(feature = "Foundation_NSOrderedSet")]
unsafe impl<ObjectType: Message> ClassType for NSOrderedSet<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSOrderedSet<ObjectType> {
type Super = NSObject;
type Mutability = ImmutableWithMutableSubclass<NSMutableOrderedSet<ObjectType>>;

Expand All @@ -275,13 +277,13 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSOrderedSet")]
pub struct NSMutableOrderedSet<ObjectType: Message = AnyObject> {
pub struct NSMutableOrderedSet<ObjectType: ?Sized = AnyObject> {
// Inherit auto traits from superclass.
__superclass: NSOrderedSet<ObjectType>,
}

#[cfg(feature = "Foundation_NSOrderedSet")]
unsafe impl<ObjectType: Message> ClassType for NSMutableOrderedSet<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSMutableOrderedSet<ObjectType> {
#[inherits(NSObject)]
type Super = NSOrderedSet<ObjectType>;
type Mutability = MutableWithImmutableSuperclass<NSOrderedSet<ObjectType>>;
Expand All @@ -299,7 +301,7 @@ __inner_extern_class!(
__inner_extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)]
#[cfg(feature = "Foundation_NSEnumerator")]
pub struct NSEnumerator<ObjectType: Message = AnyObject> {
pub struct NSEnumerator<ObjectType: ?Sized = AnyObject> {
// SAFETY: Auto traits specified below.
__superclass: UnsafeIgnoreAutoTraits<NSObject>,
// Enumerators are basically the same as if we were storing
Expand All @@ -315,7 +317,7 @@ __inner_extern_class!(
}

#[cfg(feature = "Foundation_NSEnumerator")]
unsafe impl<ObjectType: Message> ClassType for NSEnumerator<ObjectType> {
unsafe impl<ObjectType: ?Sized + Message> ClassType for NSEnumerator<ObjectType> {
type Super = NSObject;
type Mutability = Mutable;

Expand Down
2 changes: 1 addition & 1 deletion crates/icrate/src/generated
10 changes: 5 additions & 5 deletions crates/objc2/src/macros/extern_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,13 @@ macro_rules! __impl_as_ref_borrow {
macro_rules! __inner_extern_class {
(
$(#[$m:meta])*
$v:vis struct $name:ident<$($t_struct:ident $(: $b_struct:ident $(= $default:ty)?)?),* $(,)?> {
$v:vis struct $name:ident<$($t_struct:ident $(: $(?$b_sized_struct:ident)? $($b_struct:ident)? $(= $default:ty)?)?),* $(,)?> {
$superclass_field:ident: $superclass_field_ty:ty,
$($fields:tt)*
}

$(#[$impl_m:meta])*
unsafe impl<$($t_for:ident $(: $b_for:ident)?),* $(,)?> ClassType for $for:ty {
unsafe impl<$($t_for:ident $(: $(?$b_sized_for:ident +)? $b_for:ident)?),* $(,)?> ClassType for $for:ty {
$(#[inherits($($inheritance_rest:ty),+ $(,)?)])?
type Super = $superclass:ty;
type Mutability = $mutability:ty;
Expand All @@ -341,7 +341,7 @@ macro_rules! __inner_extern_class {
$crate::__emit_struct! {
($(#[$m])*)
($v)
($name<$($t_struct $(: $b_struct $(= $default)?)?),*>)
($name<$($t_struct $(: $(?$b_sized_struct)? $($b_struct)? $(= $default)?)?),*>)
(
$superclass_field: $superclass_field_ty,
$($fields)*
Expand All @@ -350,7 +350,7 @@ macro_rules! __inner_extern_class {

$crate::__extern_class_impl_traits! {
$(#[$impl_m])*
unsafe impl ($($t_for $(: $b_for)?),*) for $for {
unsafe impl ($($t_for $(: $(?$b_sized_for +)? $b_for)?),*) for $for {
INHERITS = [$superclass, $($($inheritance_rest,)+)? $crate::runtime::AnyObject];

fn as_super(&$as_super_self) $as_super
Expand All @@ -359,7 +359,7 @@ macro_rules! __inner_extern_class {
}

$(#[$impl_m])*
unsafe impl<$($t_for $(: $b_for)?),*> ClassType for $for {
unsafe impl<$($t_for $(: $(?$b_sized_for +)? $b_for)?),*> ClassType for $for {
type Super = $superclass;
type Mutability = $mutability;
const NAME: &'static $crate::__macro_helpers::str = $crate::__select_name!($name; $($name_const)?);
Expand Down
Loading

0 comments on commit 2f6e76b

Please sign in to comment.