Tech News
← Back to articles

Eurydice: a Rust to C compiler (yes)

read original related products more articles

Perhaps the greatest surprise of the last two years was, for me, the realization that people not only care about compiling C to Rust (for obvious reasons, such as, ahem, memory safety) – they also care about compiling Rust to C! Wait, what?

I wrote about this briefly a couple years ago, but the level of interest for the project, I must say, took me somewhat by surprise. So let’s talk about compiling Rust to C a little more today.

Barriers to Rust adoption

Rust is making big progress in terms of adoption, and represents a great value proposition, especially for new code. Both my former employer and my new employer, like pretty much everyone else these days, have big projects that are written in pure Rust or can have Rust components. Even Windows kernel drivers can be written in Rust now. Amazing stuff.

However, if your project is, say, an open-source library that gets compiled on a wonderfully diverse set of target architectures, OSes, distributions and toolchains, well, chances are… one of these is not going to support Rust. Think of a crypto library: there will be people out there with an obscure compiler for a weird embedded target, and they really want to compile your library, because they’ve been told not to roll out their own crypto. Or perhaps you have a format library ridden with memory errors and you want to port it to Rust. Or maybe your company has an in-house analysis that only runs on C code. Regardless of the scenario, there will always be that one legacy use-case that prevents you from switching to Rust until it’s 2035, all those LTS versions (looking at you RHEL) are finally retired, and you yourself are too close to retirement to even care anymore.

That is, unless you’re willing to use a Rust to C compiler.

Why?

Having a backwards-compat scenario where Rust can be compiled to C serves several purposes.

It allows for a gradual transition. The codebase can be ported to Rust, and refactored / cleaned up / rewritten to use all the nice Rust things (data types, pattern-matching, polymorphism, memory safety), thus making you and your developers much, much happier. Meanwhile, the C version co-exists so that you don’t alienate your userbase. It only requires maintaining a single version. The Rust code is authoritative; the C code is derived from it automatically, either on CI, or at least with a CI job that checks that the two are in sync. It allows for a census of problematic scenarios. By making the Rust version the default (and putting the fallback C behind a --write-us-an-email flag), there is finally a way to enumerate those mythical users who cannot switch to Rust just yet.

If that sounds appealing, meet Eurydice.

... continue reading