Summary
On stable Rust, Rust’s bool
in FFI has the same ABI as C’s _Bool
. Apparently this, while the case, hasn’t been formally decided. I think Rust should adopt the position that the act of shipping this feature on stable Rust and keeping it shipped for an extended period of time (ever since 1.0 even?) during which deployed code has come to rely on it should under the Rust stability policy constitute commitment to this feature.
Fact I assume to be true
Based on issue comments and by observervation of my own use of bool
in FFI appearing to work on the platforms Firefox runs on, I am assuming that it’s presently true that Rust’s bool
(and pointers to it) in FFI has the same extern "C"
ABI representation as C’s _Bool
(and pointers to it).
It’s wrong to break this, so it should be documented as reliable
There is deployed code out there that assumes that Rust bool
in extern "C"
signatures maps to C’s _Bool
. It’s easy to assume that this is correct, since rusty-cheddar
generates C headers that suggest that it works that way and running the code gives the appearance of it working.
It has come to my attention that while this actually works, there hasn’t been a formal decision that it should work and, hence, there’s a proposal to make the compiler complain to programmers who are assuming that it works.
I believe this is unproductive, because a lint complaining about bool
in FFI suggests that the equivalence of bool
and _Bool
shouldn’t be relied on suggests that the equivance might get broken, but breaking it would violate the Rust stability story, so, hence, the equivalence mustn’t be broken and suggesting that it might just causes waste of effort on the part of programmers trying to figure out what to do about the lint.
Since the combination of Rust’s stability story, the act of shipping the behavior that Rust bool
in FFI is equivalent to C _Bool
on the stable channel and deployed code relying this equivalence logically has to result in commitment to keep it so, I request that it be officially documented as being so.
Counter-counter-arguments
I’ll go ahead and address the counter-arguments I’ve seen.
Counter-argument: bool
in FFI is reserved
Counter-counter-argument: It shouldn’t matter if it’s theoretically a bug that the compiler hasn’t refused to compile code that uses bool
in extern "C"
function signatures. What should matter is that the behavior has shipped on the stable channel, has been put to use by deployed code and isn’t a soundness bug. Taking a different position would totally undermine Rust’s stability story and de facto adopt C’s approach of blaming the programmer if the programmer relies on something that seems to work but hasn’t explicitly been documented as reliable.
Counter-argument: FFI is unsafe
Counter-counter-argument: FFI is unsafe
, because it’s up to the programmer to ensure that code on the other side of the interface upholds the relevant invariants. FFI is not unsafe
as an excuse for the FFI to undergo breaking changes. In fact, while Rust’s non-FFI ABI is explicitly subject to change (and this, unlike bool
in FFI being “reserved”, is highly visibly communicated), it’s a key feature of FFI that it, in contrast to the non-FFI ABI, is not subject to breaking changes.
Counter-argument: There have been soundness fixes
Counter-counter-argument: These are opposite cases. A soundness bug threatens the whole value proposition of Rust and the breakage from the fix tends to be theoretical. In this case, it’s in practice a feature that’s in real use that bool
maps to _Bool
, so the breakage would be real, but changing it would “fix” a theoretical concern.
Counter-argument: There exist C implementations whose _Bool
is too weird to commit Rust’s bool
to match
Counter-counter-argument: Rust’s stability story should mean that there’s a commitment not to break what has already shipped. This means that Rust’s bool
in FFI has to continue to match C’s _Bool
on the Windows and System V-ish systems that Rust has already been deployed on. Suggesting that this part might be subject to change makes programmers waste time. OTOH, warning programmers about niche platforms that Rust might support in the future would be a gross misbalancing by putting theoretical future niche concerns ahead of programmer productivity on actual present mainstream and not-quite-so-mainstream systems. Rust already, quite appropriately, forgoes interop with some imaginable C implementations–most notably those that don’t provide two’s complement signed integers. If in the future Rust actually ends up targeting platforms whose C ABI is too weird for Rust’s bool
to match, dealing with that mismatch should be a problem for developers in that niche to solve and shouldn’t spill over to inconvenience everyone.