reference
reference copied to clipboard
Add "Attributes on X" for various places attributes are allowed
Various places allow attributes. We document where on the attributes page already, but each individual page for those places should also have documentation about what they allow.
- [x] Functions (#387)
- [x] Modules
- [ ] Statics
- [ ] The crate
- [ ] Items in general
- [ ] Enum variants, struct and union fields
@Centril had the idea of using a template on each attribute which would include a list of places where the attribute is valid (and the Syntax):
Syntax MetaNameValueStr
Allowed on: any item
Once we have the information where every attribute is valid, it might be worth considering adding this.
I have concerns that many of the attributes locations are not validated, and are allowed everywhere even if they are ignored. Or the behavior of some attributes that are applicable in many places (like no_mangle) is not clear. I personally prefer to only document the locations where they are not ignored, but @Centril prefers to also include the ignored locations. Perhaps the best solution is to add deprecation warnings to the ignored locations, and pretend they are not valid. I'm not a big fan of documenting bugs since there are thousands of them, they change rapidly, and are rustc-specific.
Another example is link_section which is allowed everywhere, but (I think) only applies to functions and statics (ignored everywhere else).
I have concerns that many of the attributes locations are not validated
This is something that I personally intend to fix eventually, similarly to https://github.com/rust-lang/rust/pull/57321 that did it for attribute inputs rather than locations. If the rules as they exist now (random and accidental) are documented, it will be harder to do (at least ideologically).
If the rules as they exist now (random and accidental) are documented, it will be harder to do (at least ideologically).
@petrochenkov Yeah that's pretty fair... Maybe we can document them on an issue on this repo for now with an explicit caveat re. that they may change? You'll need to know what the current behaviors are and what we think they should be to fix them in any case? And when you are done with fixing we can move them into the reference?
I think it would be reasonable to list location in which the attribute should certainly be allowed, and keep silence about other locations.
Some more validation was added via https://github.com/rust-lang/rust/pull/73461, which can help guide updating the docs on where each attribute can be placed.
More validation is being considered in https://github.com/rust-lang/rust/pull/80920.
I noticed that no_mangle says it can go on any item. However, I think it only applies to functions and statics. It also should not be used with generic type or const parameters (lifetimes are ok). There are warnings for this (UNUSED_ATTRIBUTES, NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS).
I noticed, that if link_section is the only attribute on a static, the section is created, like this:
// llvm-objdump output has `.example_section:`
#[link_section = ".example_section"]
pub static VAR1: u32 = 1;
But for a function, if link_section is the only attribute, the section is not created. For a function, a section specified in the link_section attribute is created only if the function also has an other attribute, like no_mangle, export_name or inline(never).
// llvm-objdump output does not have `.example_section:`
#[link_section = ".example_section"]
pub fn foo() {}
// llvm-objdump output has `.example_section:`
#[no_mangle]
#[link_section = ".example_section"]
pub fn foo() {}