I would assume that these two use cases are basically completely separate.
Auto-translate from C to Rust would serve as a great step to starting a porting project. Now you can incrementally re-write the "basically C" auto-ported code to "proper Rust" without dealing with FFI and other pains that come from function-by-function ports.
Fil-C is great for running software that you don't want to port. (Or don't yet have the resources to port.)
Interestingly there is probably a gap between the two. When your project is pure C you can use Fil-C. However I don't think Fil-C supports Rust. So assuming that the initial C to Rust translation doesn't produce 100% safe code (I'm not aware of any current tools that do this) you have this middle state where you can no longer compile with Fil-C but have lots of unsafe Rust code. So maybe there is a use case for Fil-Rust where you compile your Rust program so that even unsafe blocks are in fact safe. This could be used until you complete the port.
The other direction might be more interesting, in case rust drops in popularity in a couple of years, leaving behind a bunch of "let's rewrite in rust" efforts
Language popularity is cyclical; the hedge is to treat Rust as an implementation detail behind stable, language-agnostic boundaries (protocols, C ABI, WASM) and invest in strong tests/specs. If Rust wanes, migrate piecemeal: keep interfaces, reimplement modules elsewhere, and verify parity with property tests and benchmarks. Multi-agent, agentic LLM workflows can prototype alternatives in parallel, generate FFI/interop shims, and cross-check behavior to de-risk the swap without another “big rewrite.”
The article doesn't address the hard problem of figuring out array sizes.
There's some work going on as part of the DARPA TRACTOR program to work on that.
This area, of course, is the usual cause of buffer overflows.
The goal is to convert C pointers to Rust arrays, pointer arithmetic to Rust slices, and array allocations to Vec initialization. The hard problem is figuring out the sizes of arrays, which is going to require global analysis down the call chain.
If you're going to publish papers on this, please address that problem.
In a way this is strange because there us a huuuge new area of vulnerabilities caused by LLMs writing code that DWARFS the read/write out of array bounds issues C has.
I understand the issues related to LLM leaking and re-distributing "private" information, but I'm curious which category of concerns you're referring to. Would you mind giving some context (genuinely curious) ?
You can look at the vulnerabilities found graph of github. It stays about the same for years and then skyrockets up at around the time LLMs were invented.
And they are all pretty simple vulnerabilities, exploitable even to people knowing nothing about how to get root access from a binary that has an out of bounds condition somewhere in randomly shuffled memory layout in a specific version if a C program.
Automatically translating C to unsafe Rust is pointless, the resultant code is harder to read and there's no improvement in understanding how to get the code maintainable and safe, that requires tons of manual work by someone with a deep understanding of the codebase.
Generally the Rust community as well don't seem to have an answer on how to do this incrementally. In business terms we have no idea how to do work slices with demonstrable value, so no way to keep this on track and cut losses if it becomes too much work. This also strongly indicates you're 'stuck' with Rust when you're done, maybe a better and less unidiomatic C++ killer comes later and sounds like you're either going to have to rewrite the whole thing or give up.
I'm definitely open to wisdom on this if anyone disagrees because it is valuable to me and probably most of the readers of this comment section.
My 2C: What we need isn't a translater, but painless FFI. The FFI tools avail like cc and bindgen make working results most of the time, but they need [manual] wrapping.
It's kind of a similar situation (Although a bit more complicated) exposing Rust libs in python; PyO3/maturin do the job, but you have to manually wrap.
So... I would like tools that call C code from rust, but with slices etc instead of pointers.
IMO, safety and "idiomatic-ness" of Rust code are two separate concerns, with the former being easier to automate.
In most C code I've read, the lifetimes of pointers are not that complicated. They can't be that complicated, because complex lifetimes are too error prone without automated checking. That means those lifetimes can be easily expressed.
In that sense, a fairly direct C to Rust translation that doesn't try to generate idomatic Rust, but does accurately encode the lifetimes into the type system (ie. replacing pointers with references and Box) is already a huge safety win, since you gain automatic checking of the rules you were already implicitly following.
If that can be automated (which seems increasingly plausible) then the need to do such a translation incrementally also goes away.
Making it idiomatic would be a case of recognising higher level patterns that couldn't be abstracted away in C, but can be turned into abstractions in Rust, and creating those abstractions. That is a more creative process that would require something like an LLM to drive, but that can be done incrementally, and provides a different kind of value from the basic safety checks.
It's not pointless. For a start it frees you from the C toolchain so things like cross-compilation and WASM become much easier.
Secondly, it's a sensible first step in the tedious manual work of idiomatic porting. I'm guessing you didn't read the article but it's about automating some of this step too.
17 comments
[ 2.0 ms ] story [ 42.3 ms ] threadYou're better off using Fil-C.
Auto-translate from C to Rust would serve as a great step to starting a porting project. Now you can incrementally re-write the "basically C" auto-ported code to "proper Rust" without dealing with FFI and other pains that come from function-by-function ports.
Fil-C is great for running software that you don't want to port. (Or don't yet have the resources to port.)
Interestingly there is probably a gap between the two. When your project is pure C you can use Fil-C. However I don't think Fil-C supports Rust. So assuming that the initial C to Rust translation doesn't produce 100% safe code (I'm not aware of any current tools that do this) you have this middle state where you can no longer compile with Fil-C but have lots of unsafe Rust code. So maybe there is a use case for Fil-Rust where you compile your Rust program so that even unsafe blocks are in fact safe. This could be used until you complete the port.
The goal is to convert C pointers to Rust arrays, pointer arithmetic to Rust slices, and array allocations to Vec initialization. The hard problem is figuring out the sizes of arrays, which is going to require global analysis down the call chain.
If you're going to publish papers on this, please address that problem.
And they are all pretty simple vulnerabilities, exploitable even to people knowing nothing about how to get root access from a binary that has an out of bounds condition somewhere in randomly shuffled memory layout in a specific version if a C program.
Generally the Rust community as well don't seem to have an answer on how to do this incrementally. In business terms we have no idea how to do work slices with demonstrable value, so no way to keep this on track and cut losses if it becomes too much work. This also strongly indicates you're 'stuck' with Rust when you're done, maybe a better and less unidiomatic C++ killer comes later and sounds like you're either going to have to rewrite the whole thing or give up.
I'm definitely open to wisdom on this if anyone disagrees because it is valuable to me and probably most of the readers of this comment section.
It's kind of a similar situation (Although a bit more complicated) exposing Rust libs in python; PyO3/maturin do the job, but you have to manually wrap.
So... I would like tools that call C code from rust, but with slices etc instead of pointers.
In most C code I've read, the lifetimes of pointers are not that complicated. They can't be that complicated, because complex lifetimes are too error prone without automated checking. That means those lifetimes can be easily expressed.
In that sense, a fairly direct C to Rust translation that doesn't try to generate idomatic Rust, but does accurately encode the lifetimes into the type system (ie. replacing pointers with references and Box) is already a huge safety win, since you gain automatic checking of the rules you were already implicitly following.
Here's an example of the kind of unidiomatic-but-safe Rust code I mean: https://play.rust-lang.org/?version=stable&mode=debug&editio...
If that can be automated (which seems increasingly plausible) then the need to do such a translation incrementally also goes away.
Making it idiomatic would be a case of recognising higher level patterns that couldn't be abstracted away in C, but can be turned into abstractions in Rust, and creating those abstractions. That is a more creative process that would require something like an LLM to drive, but that can be done incrementally, and provides a different kind of value from the basic safety checks.
Secondly, it's a sensible first step in the tedious manual work of idiomatic porting. I'm guessing you didn't read the article but it's about automating some of this step too.
That also sounds exactly like the kind of invention that would make me fear for my job and claim AGI has all but arrived.
Just syntactically translating C code to mostly unsafe or non-idiomatic Rust seems like a pretty pointless excercise?