At shopify, we test extensively against ruby-head in order to improve performance and improve Ruby for our apps. Unlike stable Ruby releases, ruby-head is subject to breaking ABI changes on a per-commit basis. This means that extensions that rely on libruby ABI compatibility (i.e. assuming certain struct layouts / fields being available) can break on a moments notice.
These breaking changes are currently very disruptive, because it prevents us from deploying new versions of ruby-head for our apps that use Rust gems (including the core monolith and SFR).
To fix this, rb-sys should provide a ABI stability guarantees where it makes sense, so upstream crates like magnus do not have to rely on Ruby internal data structures to do their job (example). We can do this by providing implementations for the common C macros and inline functions libruby provides that are currently inaccessible from Rust.
[ ] Implement missing RSTRING_PTR, RSTRING_LEN macros in Rust for all released versions of Ruby
[ ] Add support for detecting dev (unreleased) versions of Ruby
[ ] When a dev build is detecting, skip using the Rust implementations entirely, and instead compile and link the C glue code versions (via ruby-macros feature) instead (since those should be ABI compatible, albeit more of a pain to use and slower)
[ ] Submit patches to magnus to use new Rust implementations
[ ] Mark RString and RArray types as opaque, so upstream consumers of rb-sys are forced to use the ABI stable macros instead (to ensure they are protected from breaking ABI changes).
At shopify, we test extensively against
ruby-head
in order to improve performance and improve Ruby for our apps. Unlike stable Ruby releases,ruby-head
is subject to breaking ABI changes on a per-commit basis. This means that extensions that rely on libruby ABI compatibility (i.e. assuming certain struct layouts / fields being available) can break on a moments notice.These breaking changes are currently very disruptive, because it prevents us from deploying new versions of
ruby-head
for our apps that use Rust gems (including the core monolith and SFR).For example, a recent change to the
RString
struct and subsequent update to magnus made it so extensions would not compile, and thus CI going 🔴 .To fix this,
rb-sys
should provide a ABI stability guarantees where it makes sense, so upstream crates likemagnus
do not have to rely on Ruby internal data structures to do their job (example). We can do this by providing implementations for the common C macros and inline functions libruby provides that are currently inaccessible from Rust.RSTRING_PTR
,RSTRING_LEN
macros in Rust for all released versions of Rubydev
(unreleased) versions of Rubydev
build is detecting, skip using the Rust implementations entirely, and instead compile and link the C glue code versions (viaruby-macros
feature) instead (since those should be ABI compatible, albeit more of a pain to use and slower)magnus
to use new Rust implementationsRString
andRArray
types as opaque, so upstream consumers ofrb-sys
are forced to use the ABI stable macros instead (to ensure they are protected from breaking ABI changes).