I'm trying to resolve a very technical question about interoperability with C. This talk (the link points to the relevant discussion but you might want to rewind a few seconds for context) suggests that LLVM doesn't contain the necessary logic to call every possible C function using the same declarations on all targets/platforms, and that a real C compiler is where the information about how to call every possible C function resides. It is my understanding that Rust doesn't embed clang (or replicate all of its C ABI knowledge) and that bindgen does. That would seem to suggest that the tools provided OOTB by Rust for C interop, such as repr(C) and extern C annotations, are not sufficient to interoperate correctly with every possible C function. Is that correct?
If so: does Rust issue a diagnostic for the cases that don't work without something like bindgen?
If not: how does Rust solve the platform/architecture C ABI problem mentioned in the talk?
I don't work on the Rust compiler. But from experience using Rust I can say that the rust compiler correctly implements the ABI on any platform I used it (excluding obscure bugs, but those happen between GCC and Clang as well). In practice I have never personally hit any such ABI bug. With tooling such as abi-cafe the risk of such bugs should go down.
That said, there can of course be other things that differ on the API level when working with C APIs. The most obvious is #ifdef. If someone changes the types of arguments based on platform, you need to handle that above the ABI level. This is where tools like bindgen and cbindgen comes in handy.
Generally I would use such tools anyway, as maintaining any non-trivial API binding by hand against a moving target is painful busywork. Better to generate the bindings and build suitable safe wrappers on top.
So I would say that this isn't a concern for anyone using Rust. But if you want to add support for a new architecture it could be an issue.
The short answer is: rustc reimplements that logic itself for all supported targets. When you use repr(C) and extern "C", you are relying on that reimplemented logic. Sometimes there are bugs and ambiguities, but for the most part it works.