Description
Code
extern "C" {
#[used]
static FOO: i32;
}
Current output
error: attribute must be applied to a `static` variable
--> src/lib.rs:2:5
|
2 | #[used]
| ^^^^^^^
Desired output
There should be at least a hint, or other kind of diagnostic message, explaining why #[used]
attribute is invalid in this context.
Rationale and extra context
#[used]
attribute cannot be applied to static items defined inside extern
blocks. However current compiler error, contrary to great Rust standards, does not explain why it is forbidden, or how to fix it. Moreover it can be confusing to newbie users. To the information "attribute must be applied to a static
variable", one could say "But it is static. Look, it says it right there".
I would expect a hint, or another diagnostic that would explain that the #[used]
attribute is used on static items that are defined inside crate, and extern
blocks are used to declare an item, that exists elsewhere. Using this attribute inside extern
block means that user either does not understand how #[used]
attribute works, or how extern
blocks work and a hint pointing it out to them could be helpful.
This would also be more inline with other errors related to incorrectly using static items inside extern
blocks. For example assigning value to such static will result in following error message:
extern "C" {
static FOO: i32 = 42;
}
error: incorrect `static` inside `extern` block
--> src/lib.rs:2:12
|
1 | extern "C" {
| ---------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body
2 | static FOO: i32 = 42;
| ^^^ -- the invalid body
| |
| cannot have a body
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
Here compiler provides also notes, explaining why this code does not work and directs user to documentation that could be useful in this context.
Other cases
A similar case could be made for the #[no_mangle]
attribute. Using it on static item in extern
block produces following warning (which will become error in the future):
extern "C" {
#[no_mangle]
static FOO: i32;
}
warning: `#[no_mangle]` has no effect on a foreign static
--> src/lib.rs:2:5
|
2 | #[no_mangle]
| ^^^^^^^^^^^^ help: remove this attribute
3 | static FOO: i32;
| ---------------- foreign static
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: symbol names in extern blocks are not mangled
= note: `#[warn(unused_attributes)]` on by default
The Rust Reference says that #[no_mangle]
implies #[used]
:
Additionally, the item will be publicly exported from the produced library or object file, similar to the used attribute.
Therefore using this attribute can be caused by the same fallacy - user not understanding that extern
blocks refer to, well, external items, and not to those that are exported from their crate. Adding similar hint to this warning (and future error) could also help users making this error.
PS. Actually the same argument could be made for other ABI attributes, like #[link_section]
and #[export_name]
.
Rust Version
rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7
Anything else?
No response