8000 Future of this project and discussion about `objc2` · Issue #729 · servo/core-foundation-rs · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Future of this project and discussion about objc2 #729
Open
@madsmtm

Description

@madsmtm

Hey @waywardmonkeys, @jrmuizel, @mrobinson and @wusyong (and CC @tmandry and @simlay).

Over the past few years, I've been working on replacements for the crates in this repo in the objc2 project, see #513 and #628 for some previous discussion. To rehash the benefits of the objc2-* crates:

  • Code generation from headers, which means that basically every upstream API is available (only a few explicitly skipped APIs aren't), and this will remain true even as Apple releases new SDK versions over time (since we only need to rerun the generator).
  • Automatic memory management, all objects are wrapped by the code generator in either objc2::rc::Retained or objc2_core_foundation::CFRetained, which will release the object on Drop. The generator knows about the "create rule" and about opt-outs like CF_RETURNS_NOT_RETAINED etc. (so it will do this correctly with a much higher probability than if a human did it).
  • Type-safety, especially compared to cocoa and cocoa-foundation where everything is just an extension trait on the id pointer.

I'm motivated in bringing these benefits to the entirety of the Apple+Rust ecosystem, as I think the soundness, correctness and ergonomics improvements here are quite significant. To that end, I've been slowly migrating major Rust projects, see madsmtm/objc2#174.

A recent milestone is that I've released objc2-core-foundation v0.3.1, which I believe now covers everything that core-foundation does! I've also assessed every open issue and pull-request in this repo, and made sure that they're either resolved or tracked in the objc2 repo, see madsmtm/objc2#719. So at this point, I'd like to start discussing the future of this project, and how we can migrate Servo and other users to the objc2-* crates (assuming you agree that's a goal, if not then I'd also like to discuss that!)

My ideal scenario would be that the crates in this repo were marked #![deprecated] with re-exports of the objc2-* variants, both to give users an easier migration path, and because in a way it'd "bless" the objc2 crates, but I can see other solutions, including any of the following variations:

  • Only do this for cocoa and cocoa-foundation (these are where objc2-* would be the most valuable).
  • Soft-deprecate the crates in the README only, but without actually marking it #![deprecated].
  • Publish an advisory to the RUSTSEC advisory database (my own preference would be not to, at least not yet).

A few drawbacks to consider:

  • It is a fair amount of churn. I don't believe it to be unnecessary churn though, there really are a lot of bugs out there in Apple+Rust-related code, and a lot of them could be alleviated with the objc2-* crates.
  • objc2-* crates are a bit less stable than core-foundation-rs crates. I do tend to be conservative of breaking changes, and to plan ahead to allow spacing them out as much as possible.
  • It is my understanding that Firefox/Mozilla vets/audits every dependency, and that the objc2-* crates haven't been audited, so this might hurt them until that happens? CC @ErichDonGubler and @jimblandy maybe?
  • This could be seen as a supply-chain attack. Don't know how to alleviate that, other than having people review my code ;)
  • Bus factor, objc2 has fewer maintainers. I'd love to get others on board though, just say so if you want to! Or join the Matrix workspace to start with.

Crate status / comparison

Note that I'm not entirely done transitioning things here, see the below table for the current status (which is probably slightly incorrect, there's bound to be something I've missed):

Servo crate objc2 crate Comparison
cocoa objc2-app-kit Fully superseded ✅
cocoa-foundation objc2-foundation Fully superseded ✅
core-foundation-sys objc2-core-foundation Fully superseded ✅
core-foundation objc2-core-foundation Fully superseded ✅
core-graphics-types objc2-core-foundation Fully superseded ✅
core-graphics objc2-core-graphics Missing CGDirectDisplayID wrapper and most functions are still unsafe ⚠️
core-text objc2-core-text Still a fair bit of work to do to make it as nice ❗️
io-surface objc2-io-surface Fully superseded ✅

But I do intend to resolve this, so I still feel it's valuable to start discussing migration now.

How objc2-core-foundation differs from core-foundation

Just to get everyone up to speed, here's a quick overview of the differences.

The memory management strategy is as follows:

core-foundation objc2-core-foundation
CFString CFRetained<CFString>
&CFString &CFRetained<CFString>
CFStringRef *mut CFString
__CFString CFString
Not really possible &CFString

That is, objc2-core-foundation only has a single type that represents CFString, and memory management (CFRetain/CFRelease) is instead handled by a single generic wrapper type. This also meant that while I did initially consider building upon core-foundation instead of creating a new crate, it wasn't really an option in the end, as the internals are just too different.

objc2-core-foundation also avoids the *-sys split, instead preferring to expose everything in the same crate (again, to avoid a proliferation of types). A few of my guiding principles API-wise:

  • Expose all internals such that users never need to write extern "C" { ... } themselves.
  • Make everything as nice to use as possible when coming from Rust. Functions are exposed as associated functions/methods, conversions to/from common Rust types are provided.
  • Be performance-minded when creating wrappers. For example, I wouldn't add a CFURL -> String conversion, since that requires at least two CoreFoundation functions to be called. Instead, CFURL -> CFString is provided, and so is CFString -> String.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0