The reason to pay this cost is that the alternatives are: (1) do nothing: keep developing solely in C, (2) rewrite the big C project in Rust in its entirety. The cost of option (1) is significant: memory safety errors contribute to 70% of defects not detected by test [1]. Even with static+dynamic checking tools, developers keep introducing bugs into C projects that aren't possible in safe Rust [2]. The cost of option (2) is significant risk. Big C projects have grown over time and have many implicit requirements already satisfied. Discovering all of those incidental bugs and features that are necessary takes a long time and scales with the size of the project.
[1] https://msrc-blog.microsoft.com/2019/07/16/a-proactive-appro...
[2] http://blog.vmsplice.net/2020/08/why-qemu-should-move-from-c...
(I have some ideas of what you may say but am curious! You clearly have strong feelings here.)
However, AOSP is massive. It is HUGE. And complicated to build. I really, really doubt this addition will make a huge deal.
This is the same for many of the huge projects adopting Rust. The worst one so far is the Linux kernel IMO, because at least that is mostly C and GNU Make. And yet even there, that still isn't that bad.
Also, as far as bugs at the interface, I'm pretty sure it's a wash. C and Rust are ABI compatible to the extent that matters. The "subtle bugs" are most likely going to be ones that could've existed without the additional complexity of a new language and an interface between them. It's no worse than say, JNI, which doesn't seem to be a serious issue.
I'm pretty sure the benefits of Rust can outweigh this cost. As long as you can build the project, you don't really need to understand 2 toolchains to contribute unless your contribution lands across a boundary between 2 toolchains. On a lot of really large projects this may already be the case anyways.
Having to maintain this interface between the language does come with its own set of problems but is well worth the tradeoff especially if you can spend most of your time in one language or the other.
I think the idea of this article is that you don’t need to understand two tool chains but instead can focus on the harder task of understanding two languages.
Rust does not consume C headers. For every function and data structure of the API surface you gonna need two language projections, C header and Rust source file. For large API surfaces, especially when both sides of the FFI evolve over time, bugs are inevitable.
The problem is not specific to Rust. It affects all languages, except C++ and Objective-C which are backward compatible.
You do not have to write these things, nor keep track of changes, by hand.
The most popular C library in the world is probably the standard one. Yet in https://github.com/rust-lang/libc I don’t see any glue automatically generated from C headers, everything’s written manually.
Other examples: https://github.com/servo/rust-png/ https://github.com/bozaro/lz4-rs
There are a few big reasons to consider avoiding parsing the C headers directly:
* The C headers might use features in C that are not compatible with the C parser or Rust ABI itself. (C unions used to be a big headache, and bitfields probably still are.). Manually specifying only what you want to import avoids that issue entirely.
* As an extended note to the above, many libraries (particularly your system's implementation of libc) are actually not written in any standard C dialect but instead have a lot of compiler-specific things tacked onto it that make it even more difficult to parse and handle correctly than regular C/C++.
* Parsing the C headers requires having them installed and being able to find them correctly. When you start dealing with cross-compilation toolchains, this can be a major hassle.
Yet, at least. I hope one day it can, transparently.
In whichever case, we should be careful not to overstate the complexity of integrating Rust and C. Specifically, bringing in any given C dependency means integrating its bespoke build system (and those of each transitive dependency) with that of your project (or more likely, you punt on reproducible builds and instead push the dependency hell onto every contributor) which doesn't strike me as considerably less work than integrating the Rust toolchain (and since Rust has sane, standard build/dependency tooling, it's pretty much a one-time cost rather than a once-per-dependency cost).