"Just use bindgen" is a cop-out, not a solution. It is technically correct, merely by marking all APIs unsafe. But as the Chromium document describes, this introduces a lot of noise that can mask the more involved proofs.
What Chromium wants is, again, not a way to generate soundness proofs, but a way to consolidate large numbers of similar proofs into a single place (the invocation of the binding macro), so that the remaining proofs can stand out.
Please, do us all a favor and stop misattributing absurdities to Chromium and autocxx. This is a useful part of the design space, ill-served by bindgen alone. Chromium is not the first project to hit it, nor will it be the last. For example, here is a Servo/Gecko dev's take on the subject: https://www.reddit.com/r/rust/comments/ielvxu/the_cxx_debate...
> "Just use bindgen" is a cop-out, not a solution. It is technically correct, merely by marking all APIs unsafe. But as the Chromium document describes, this introduces a lot of noise that can mask the more involved proofs.
Chromium does not want to use `unsafe` on every call. The solution is simple, write a safe wrapper, that uses `unsafe` once.
> but a way to consolidate large numbers of similar proofs into a single place
That wasn't my read of their comment. If that's what they want, then the patched `cxx` crate which requires `unsafe` would give them exactly this.
The reddit user mentions:
> The key issue that people get worked up about, is that all C++ is unsafe,
This is not what we are talking about here. Lot of C++ code is safe, and writing a safe wrapper over C++ that's obviously safe is a one liner. What's problematic is doing so without checking _and_ without writing unsafe, by assuming that all C++ code is safe, which is what a library that asks you for a path to a headerfile and that will automatically generate safe wrappers in safe rust without asking even if the header file silently changes seems to encourage.
I also worked on one of the largest FFI Rust projects, and what one does is automatically generate thousands of unsafe C bindings, and have a crate exposing safe wrappers. Every time you need to call one FFI you either use the safe wrapper, or you add one if there isn't one. Very often, safe C wrappers weren't trivial, because what the FFI bindings were doing was inherently unsafe, and the amount of abstraction required to make that safe was prohibitive (and many many projects have run into this, Vulkan, wayland, ...). Then you either spend a lot of time into a safe abstraction, or you just use the unsafe API. Automatically generating safe wrappers instead just sounds like a bad idea, one would just be pushing all those issues onto safe Rust, which is not where they belong.
This is exactly what the first reply to that reddit user mentions, and here is your reddit user's reply to that, in which they explain that they were mostly referring to FFI when it comes to splicing Rust into C++: https://www.reddit.com/r/rust/comments/ielvxu/the_cxx_debate...
Calling Rust from C++ is a _very_ different use case from just calling C++ from Rust, which is what the Chromium devs mention is their primary concern:
> we are primarily concerned with the ability for new Rust code to call into existing C++ code
It's so different that one can in fact easily generate "safe" C++ bindings to safe Rust.
> The solution is simple, write a safe wrapper, that uses `unsafe` once.
This is the thing I'm calling a cop-out. Chromium wants to avoid the error-prone boilerplate of writing out all those safe wrappers, by asserting in a single place that a whole collection of C++ functions are always safe to call with any arguments that match their (generated Rust-side) type.
> That wasn't my read of their comment. If that's what they want, then the patched `cxx` crate which requires `unsafe` would give them exactly this.
Yes, this is what I have been telling you. The Chromium document also says this at the end of point #1: "This particular property is satisfied by dtolnay’s marvellous cxx library already."
> > The key issue that people get worked up about, is that all C++ is unsafe,
>
> This is not what we are talking about here. Lot of C++ code is safe, and writing a safe wrapper over C++ that's obviously safe is a one liner.
We need to be careful with terminology here. All C++ code is unsafe in the sense that its soundness is unchecked by the compiler. Some C++ is also unsafe in the sense of an `unsafe fn`, placing additional expectations on its callers which are not captured by the type signature.
I'm repeating myself now, but it is absolutely possible to take a C++ header file, review the functions it declares, and decide "yes, the wrappers generated by cxx for these functions would all be sound." This is the case where autocxx helps- once you have such a header file, generating a bunch of safe wrappers is much less error prone than writing and maintaining them by hand.
You are correct that Vulkan/Wayland/etc. are usually not conducive to this. But that is why I linked that Reddit comment- the Chromium devs invoking cxx also control the APIs they're feeding it! The reply you linked is not talking about calling Rust from C++, but about this approach of calling C++ which you also own from Rust.
Once you control both sides of the language boundary, changes to the header are a totally different matter. All the thought that goes into preserving those functions' contracts, or updating their callers when they change, must "simply" take the Rust code (and its generated wrappers) into account as well. This is what "all C++ code is unsafe" means- regardless of whether or how Rust is involved, changes to C++ functions must consider their impact on soundness.
My only complain about autocxx remains that it does not require `unsafe`, but if they adopt the same fix that the `cxx` crate wants to adopt, that complain is gone. I hope the Chromium devs would be "ok" with such a small amount of unsafe code that condenses the proofs of all APIs being wrapped.
We kind of tossed aside the discussion of unsafe vs safe macros, but I'd understand some people see that differently (macros expand Rust code, but IMO they are not that different from generics, and we do have safe and unsafe generics; right now, AFAICT, we only have safe macros).
Yeah, I do think it might be interesting (if somewhat of a backwards compatibility problem) to introduce the concept of an "unsafe macro." Along with https://github.com/rust-lang/rfcs/pull/2585 it would really emphasize the proof obligation-vs-discharge model of `unsafe`.
I think that would be worth doing, but more than the backward compat problem, the main complication I see would be in the syntax/grammar/macro expansion.
Like, say we wanted to make cxx or autocxx macros unsafe. We'd need to allow at item scope writing this:
mod foo {
unsafe { my_unsafe_macro!() }
}
and we'd "somehow" have to check that unsafe macros are only expanded within unsafe "scopes", rejecting the program otherwise (can't be a type error because we can't do type checking before macro expansion). Also, these unsafe scopes would need to export all the items, etc.
I don't know. Seems like a lot of contortion for something that could be solved with just a rename like other have proposed, e.g., unsafe_autocxx_include!(...);
Might be worth opening an internal threads about this. Maybe Centril could shed more like on how hard this would actually be.
Most (all?) macros that I regularly use are sound (the derives, println!, debug!, offset_of!, pin_mut!...). So it might also be worth looking into how common of a problem this is. I've seen soundness bugs in macros before (offset_of!), but these were always bugs. This is the first time I recall a macro that's unsound by design.
What Chromium wants is, again, not a way to generate soundness proofs, but a way to consolidate large numbers of similar proofs into a single place (the invocation of the binding macro), so that the remaining proofs can stand out.
Please, do us all a favor and stop misattributing absurdities to Chromium and autocxx. This is a useful part of the design space, ill-served by bindgen alone. Chromium is not the first project to hit it, nor will it be the last. For example, here is a Servo/Gecko dev's take on the subject: https://www.reddit.com/r/rust/comments/ielvxu/the_cxx_debate...