Skip to content

Commit

Permalink
Add CFRetained
Browse files Browse the repository at this point in the history
Add a Retained-like pointer for CoreFoundation-like types.

Part of #556.
  • Loading branch information
madsmtm committed Jan 9, 2025
1 parent de1c9d9 commit 0cfd5fc
Show file tree
Hide file tree
Showing 12 changed files with 495 additions and 14 deletions.
8 changes: 8 additions & 0 deletions crates/header-translator/src/rust_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,14 @@ impl Ty {
}
}

pub(crate) fn is_cf_type(&self) -> bool {
if let Self::TypeDef { is_cf, .. } = self {
*is_cf
} else {
false
}
}

pub(crate) fn is_objc_bool(&self) -> bool {
match self {
Self::Primitive(Primitive::ObjcBool) => true,
Expand Down
23 changes: 23 additions & 0 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,29 @@ impl Stmt {
_ => error!("unknown"),
});

// Don't map `CFRetain`, `CFRelease`, `CFAutorelease`, as well
// as custom ones like as `CGColorRelease`.
//
// Same as what Swift does:
// <https://github.com/swiftlang/swift/blob/swift-6.0.3-RELEASE/lib/ClangImporter/ImportDecl.cpp#L8435-L8452>
//
// Users can achieve (almost) the same by using `CFRetained`
// and `ManuallyDrop`, and this is clearer and safer.
//
// Besides, these do not have the necessary memory management
// attributes (cf_consumed/cf_returns_retained), and as such
// cannot be mapped correctly without extra hacks.
if id.name.ends_with("Retain")
|| id.name.ends_with("Release")
|| id.name.ends_with("Autorelease")
{
if let Some((_, first_arg_ty)) = arguments.first() {
if first_arg_ty.is_cf_type() {
return vec![];
}
}
}

let body = if entity.is_inline_function() {
Some(())
} else {
Expand Down
28 changes: 18 additions & 10 deletions crates/objc2/src/rc/retained_forwarding_impls.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
//! Trivial forwarding impls on `Retained`.
//! Trivial forwarding impls on `Retained`-like types.
//!
//! Kept here to keep `id.rs` free from this boilerplate.
//! Kept here to keep `retained.rs` free from this boilerplate, and to allow
//! re-use in `objc2-core-foundation` (this file is symlinked there as well).
#![forbid(unsafe_code)]

use alloc::borrow;
use alloc::string::String;
use alloc::vec::Vec;
use core::borrow::Borrow;
use core::cmp::Ordering;
use core::fmt;
use core::future::Future;
use core::hash;
use core::pin::Pin;
use core::task::{Context, Poll};
#[cfg(feature = "std")] // TODO: Use core::error::Error once 1.81 is in MSRV
use std::error::Error;
#[cfg(feature = "std")]
use std::io;

use super::Retained;
Expand Down Expand Up @@ -206,7 +207,7 @@ where
}
}

impl<T: ?Sized> borrow::Borrow<T> for Retained<T> {
impl<T: ?Sized> Borrow<T> for Retained<T> {
fn borrow(&self) -> &T {
// Auto-derefs
self
Expand All @@ -226,12 +227,14 @@ impl<T: ?Sized + AsRef<U>, U: ?Sized> AsRef<U> for Retained<T> {
}
}

#[cfg(feature = "std")]
impl<T: ?Sized + Error> Error for Retained<T> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
(**self).source()
}
}

#[cfg(feature = "std")]
impl<T: ?Sized> io::Read for Retained<T>
where
for<'a> &'a T: io::Read,
Expand All @@ -247,12 +250,12 @@ where
}

#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
(&**self).read_to_end(buf)
}

#[inline]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
(&**self).read_to_string(buf)
}

Expand All @@ -262,6 +265,7 @@ where
}
}

#[cfg(feature = "std")]
impl<'a, T: ?Sized> io::Read for &'a Retained<T>
where
&'a T: io::Read,
Expand All @@ -277,12 +281,12 @@ where
}

#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
(&***self).read_to_end(buf)
}

#[inline]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
(&***self).read_to_string(buf)
}

Expand All @@ -292,6 +296,7 @@ where
}
}

#[cfg(feature = "std")]
impl<T: ?Sized> io::Write for Retained<T>
where
for<'a> &'a T: io::Write,
Expand Down Expand Up @@ -322,6 +327,7 @@ where
}
}

#[cfg(feature = "std")]
impl<'a, T: ?Sized> io::Write for &'a Retained<T>
where
&'a T: io::Write,
Expand Down Expand Up @@ -352,6 +358,7 @@ where
}
}

#[cfg(feature = "std")]
impl<T: ?Sized> io::Seek for Retained<T>
where
for<'a> &'a T: io::Seek,
Expand All @@ -367,6 +374,7 @@ where
}
}

#[cfg(feature = "std")]
impl<'a, T: ?Sized> io::Seek for &'a Retained<T>
where
&'a T: io::Seek,
Expand Down
3 changes: 3 additions & 0 deletions framework-crates/objc2-core-foundation/Cargo.modified.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[features]
# Uses the nightly derive_coerce_pointee feature to make conversions more ergonomic.
unstable-coerce-pointee = []
1 change: 1 addition & 0 deletions framework-crates/objc2-core-foundation/Cargo.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions framework-crates/objc2-core-foundation/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,6 @@ impl hash::Hash for CFType {
}

crate::__cf_type_objc2!(CFType, crate::__cf_macro_helpers::Encoding::Void);

// NOTE: impl AsRef<CFType> for AnyObject would probably not be valid, since
// not all Objective-C objects can be used as CoreFoundation objects (?)
5 changes: 5 additions & 0 deletions framework-crates/objc2-core-foundation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! [apple-doc]: https://developer.apple.com/documentation/corefoundation/
//! [framework-crates]: https://docs.rs/objc2/latest/objc2/topics/about_generated/index.html
#![no_std]
#![cfg_attr(feature = "unstable-coerce-pointee", feature(derive_coerce_pointee))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
// Update in Cargo.toml as well.
#![doc(html_root_url = "https://docs.rs/objc2-core-foundation/0.2.2")]
Expand All @@ -25,6 +26,8 @@ mod cf_type;
mod generated;
#[cfg(feature = "CFCGTypes")]
mod geometry;
mod retained;
mod type_traits;

#[cfg(feature = "CFBase")]
pub use self::base::*;
Expand All @@ -34,6 +37,8 @@ pub use self::bundle::CFBundleRefNum;
pub use self::generated::*;
#[cfg(feature = "CFCGTypes")]
pub use self::geometry::*;
pub use self::retained::CFRetained;
pub use self::type_traits::Type;

// MacTypes.h
#[allow(dead_code)]
Expand Down
Loading

0 comments on commit 0cfd5fc

Please sign in to comment.