You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The T-compiler and T-lang teams signed off here, that
bool has the same representation as _Bool
where on every platform that Rust currently supports this implies that:
bool has a size and an alignment of 1,
true as i32 == 1 and false as i32 == 0, EDIT: that is always true, the valid bit patterns of bool is what matters here, e.g., on a platform where bool has the same size as i8, whether transmute::<_, i8>(true) == 1 and transmute::<_, i8>(false) == 0
These two properties are not guaranteed by Rust, and unsafe code cannot rely on these. In the last UCG WG meeting it was unclear whether we want to guarantee these two properties or not. As @rkruppe pointed out, this would be guaranteeing something different and incompatible with what T-lang and T-compiler guaranteed.
Note: any change that the UCG WG proposes will have to go through the RFC process anyways, were it might be rejected. This issue is being raised with stakeholders to evaluate whether there is something that needs changing or not, and if so, whether the change is possible, has chances to achieve consensus, etc.
The following arguments have been raised (hope I did not miss any):
T-lang and T-compiler did not specify which version of the C standard _Bool conforms to. In C++20 and C20, P0907r4 (C++) and N2218 (C) specify that:
bool and _Bool contain no padding bits (only value bits),
1 == (int)true and 0 == (int)false.
In some of the merged PRs of the UCG we have already specified that the platform's C implementation needs to comply with some, e.g., C17 or "latest" C standard properties (e.g. for repr(C) struct layout). If we end up requiring C20 for representation / validity of repr(C), we end up guaranteeing these properties. AFAICT the only property about bool that would remain as implementation-defined is its size and alignment.
In Representation of bool, integers and floating points #9 / added floating point/int summary #49 , we ended up requiring that C's CHAR_BITS == 8. This implies that if CHAR_BITS != 8 then bool cannot have the same representation as _Bool. Some stakeholders still wanted to be able to do C FFI with these platforms, e.g. @briansmith suggested that Rust should diagnose, e.g., using bool on FFI on these platforms (Representation of bool, integers and floating points #9 (comment)), but that interfacing with those platforms via C FFI (e.g. against assembly) should still be possible (e.g. in a DSP where CHAR_BITS == 16 passing a u16 to C / assembly / ... expecting a char or 16 bit integer should be doable).
What exactly T-lang and T-compiler actually ended up guaranteeing isn't 100% clear. In Lint for the reserved ABI of bool rust#46176 the decision seems to be that bool == _Bool, but the PR that was actually merged only mentions that bool has a size of 1: Document the size of bool rust#46156. This might be an oversight in the docs, and some have mention that the reference is "non-normative". @briansmith pointed out (here and here) that bool ABI (e.g. integer class or something else?), alignment, bit patterns denoting true and false, etc. don't appear to be properly documented. @gankro summarized the status quo in Rust Layout and ABIs document and mentioned that projects like Firefox rely on these extra guarantees for correctness (e.g. for bindgen, etc. to work properly, see here.
There are a couple of comments by @withoutboats that I think show both T-lang and T-compiler's rationale and the spirit behind their decision, here:
I worry that if we don't specify bool as equivalent to C and C++ booleans, people will need to use c_bool in FFI to be cross platform compatible.
I worry that if we don't specify bool as byte sized, people will create a struct Bool(u8) to get that guarantee & keep their structs small.
People could come to the conclusion that they need a c_bool type for their FFI to be forward compatible with platforms we don't yet support. I think defining it as the same representation as _Bool / C++ bool makes it the least likely someone does something painful to avoid entirely hypothetical problems.
So even if the docs say that bool has a size of 1, and that's it, I believe that this last comment shows that the spirit of T-lang and T-compiler decision was to spare people from creating a c_bool type to be forward compatible on C FFI with platforms that we might never properly support.
I think that the open questions that have to be clarified, are:
Should we require C20 compatibility for _Bool, or do we want to stay backwards compatible with C99/11/17 ? (in this case, people can only rely on, e.g., true == 1 on targets where the platform implementation is C20 "conforming" at least w.r.t. _Bool)
Do we want to require that bool has a size and an alignment of 1 ? (in the hypothetical case that we ever support a platform where this is not the case, we could raise an improper_ctype warning / error on the platform, or some other form of diagnostic, as @briansmith suggested). This would be a change incompatible withbool == _Bool, might lead people to create and use a c_bool type, etc.
The T-compiler and T-lang teams signed off here, that
where on every platform that Rust currently supports this implies that:
boolhas a size and an alignment of1,true as i32 == 1andfalse as i32 == 0, EDIT: that is always true, the valid bit patterns ofboolis what matters here, e.g., on a platform whereboolhas the same size asi8, whethertransmute::<_, i8>(true) == 1andtransmute::<_, i8>(false) == 0These two properties are not guaranteed by Rust, and
unsafecode cannot rely on these. In the last UCG WG meeting it was unclear whether we want to guarantee these two properties or not. As @rkruppe pointed out, this would be guaranteeing something different and incompatible with what T-lang and T-compiler guaranteed.The following arguments have been raised (hope I did not miss any):
T-lang and T-compiler did not specify which version of the C standard
_Boolconforms to. In C++20 and C20, P0907r4 (C++) and N2218 (C) specify that:booland_Boolcontain no padding bits (only value bits),1 == (int)trueand0 == (int)false.In some of the merged PRs of the UCG we have already specified that the platform's C implementation needs to comply with some, e.g., C17 or "latest" C standard properties (e.g. for
repr(C) structlayout). If we end up requiring C20 for representation / validity ofrepr(C), we end up guaranteeing these properties. AFAICT the only property aboutboolthat would remain as implementation-defined is its size and alignment.In Representation of bool, integers and floating points #9 / added floating point/int summary #49 , we ended up requiring that C's
CHAR_BITS == 8. This implies that ifCHAR_BITS != 8thenboolcannot have the same representation as_Bool. Some stakeholders still wanted to be able to do C FFI with these platforms, e.g. @briansmith suggested that Rust should diagnose, e.g., usingboolon FFI on these platforms (Representation of bool, integers and floating points #9 (comment)), but that interfacing with those platforms via C FFI (e.g. against assembly) should still be possible (e.g. in a DSP whereCHAR_BITS == 16passing au16to C / assembly / ... expecting acharor 16 bit integer should be doable).What exactly T-lang and T-compiler actually ended up guaranteeing isn't 100% clear. In Lint for the reserved ABI of bool rust#46176 the decision seems to be that
bool == _Bool, but the PR that was actually merged only mentions thatboolhas a size of1: Document the size of bool rust#46156. This might be an oversight in the docs, and some have mention that the reference is "non-normative". @briansmith pointed out (here and here) thatboolABI (e.g. integer class or something else?), alignment, bit patterns denotingtrueandfalse, etc. don't appear to be properly documented. @gankro summarized the status quo in Rust Layout and ABIs document and mentioned that projects like Firefox rely on these extra guarantees for correctness (e.g. forbindgen, etc. to work properly, see here.There are a couple of comments by @withoutboats that I think show both T-lang and T-compiler's rationale and the spirit behind their decision, here:
and here:
So even if the docs say that
boolhas a size of1, and that's it, I believe that this last comment shows that the spirit of T-lang and T-compiler decision was to spare people from creating ac_booltype to be forward compatible on C FFI with platforms that we might never properly support.I think that the open questions that have to be clarified, are:
_Bool, or do we want to stay backwards compatible with C99/11/17 ? (in this case, people can only rely on, e.g.,true == 1on targets where the platform implementation is C20 "conforming" at least w.r.t._Bool)boolhas a size and an alignment of1? (in the hypothetical case that we ever support a platform where this is not the case, we could raise animproper_ctypewarning / error on the platform, or some other form of diagnostic, as @briansmith suggested). This would be a change incompatible withbool == _Bool, might lead people to create and use ac_booltype, etc.cc @rkruppe @withoutboats @briansmith @gankro @joshtriplett @cuviper @whitequark @est31 @SimonSapin