Skip to content

Commit

Permalink
Improve extern_class! safety section
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Jul 17, 2022
1 parent 09668b1 commit ff8991c
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions objc2-foundation/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@
///
/// # Safety
///
/// The specified inheritance chain must be correct (including in the correct
/// order), and the types in said chain must be valid as Objective-C objects -
/// this is easiest to ensure by also creating those using this macro.
/// The specified inheritance chain must be correct, including in the correct
/// order, and the types in said chain must be valid as Objective-C objects
/// (this is easy to ensure by also creating those using this macro).
///
/// The object must respond to standard memory management messages (this is
/// upheld if `NSObject` is part of its inheritance chain).
///
///
/// # Example
Expand Down Expand Up @@ -208,13 +211,31 @@ macro_rules! __inner_extern_class {
$($p_v $p: $pty),*
}

unsafe impl<$($t $(: $b)?),*> $crate::objc2::Message for $name<$($t),*> { }

// SAFETY:
// - The item is FFI-safe with `#[repr(C)]`.
// - The encoding is taken from the inner item, and caller verifies
// that it actually inherits said object.
// - The rest of the struct's fields are ZSTs, so they don't influence
// the layout.
unsafe impl<$($t $(: $b)?),*> $crate::objc2::RefEncode for $name<$($t),*> {
const ENCODING_REF: $crate::objc2::Encoding<'static>
= <$inherits as $crate::objc2::RefEncode>::ENCODING_REF;
}

// SAFETY: This is essentially just a newtype wrapper over `Object`
// (we even ensure that `Object` is always last in our inheritance
// tree), so it is always safe to reinterpret as that.
//
// That the object must work with standard memory management is upheld
// by the caller.
unsafe impl<$($t $(: $b)?),*> $crate::objc2::Message for $name<$($t),*> {}

impl<$($t $(: $b)?),*> $name<$($t),*> {
$v fn class() -> &'static $crate::objc2::runtime::Class {
$crate::objc2::class!($name)
}
}

// SAFETY: An instance can always be _used_ in exactly the same way as
// it's superclasses (though not necessarily _constructed_ in the same
// way, but `Deref` doesn't allow this).
Expand Down

0 comments on commit ff8991c

Please sign in to comment.