Specifying linkage on externs silently removes indirection #31508
Labels
A-codegen
Area: Code generation
A-linkage
Area: linking into static, shared libraries and binaries
C-bug
Category: This is a bug.
requires-nightly
This issue requires a nightly compiler in some way.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
When compiling the following code:
using
running
./externs
will output something like the following:Wat.
Taking a look at the IR:
So, Rust removes a layer of indirection defining
static explicitvar: [u8;10]
and adding a new variablestatic _rust_extern_with_linkage_explicitvar: *const [u8;10]=&explicitvar
. All mentions ofexplicitvar
in Rust source code get replaced with_rust_extern_with_linkage_explicitvar
. This results in the C version and this new Rust version not having the same type! To get “correct” behavior in the example above, you would need to definestatic explicitvar: *const *const [u8;10]
instead.This weird assymmetry between the types associated with symbols in Rust and in C is a source of great confusion and can easily lead to bugs. In the example above, we just read 2 bytes past some pointer by interpreting it as a 10-byte array.
This weird behavior was introduced in #12556 (see also #11978), the rationale being weak linkage and the fact that some pointers can't be null in the Rust typesystem. While true, I don't think that's sufficient rationale to add this layer of indirection. I think the layer of indirection should be removed completely. For weak linkage, a restriction can be added to allow only zeroable types.
The text was updated successfully, but these errors were encountered: