Attributes come in two types: inert (or built-in) and active (non-builtin).
These attributes are defined in the compiler itself, in compiler/rustc_feature/src/builtin_attrs.rs and in the attribute parsers.
Examples include #[allow] and #[macro_use].
These attributes have several important characteristics:
use allow as foo will compile, but writing #[foo] will produce an error.#[allow], #[warn], #[deny], and #[forbid], rather than the behavior coming from the expansion of the attributes themselves.For more information on these attributes, see the chapter about attribute parsing.
Warning: Name resolution ambiguity potential when adding new builtin attributes
Please note that adding new builtin attributes (whose name is not reserved, i.e. a new builtin attribute whose name does not start with rustc), even if unstable-gated, can introduce breakage from name resolution ambiguity in stable code if (1) the stable code has a macro of the same name which gets re-exported, or (2) or a proc-macro derive helper attribute of the same name.
Typically, the builtin attributes probably has to start out as #[rustc_foo] instead of #[foo] to avoid colliding with user-defined macros and proc-macro helper attributes. Then, prior to stabilization, a rename to #[foo] should be done separately with a crater run to assess fallout, with a deliberate breakage FCP proposal for T-lang to consider.
Remember also that crater is not exhaustive and does not contain all existing stable code.
See:
These attributes are defined by a crate - either the standard library, or a proc-macro crate.
Important: Many non-builtin attributes, such as #[derive], are still considered part of the core Rust language. However, they are not called ‘builtin attributes’, since they have a corresponding definition in the standard library.
Definitions of non-builtin attributes take two forms:
#[proc_macro_attribute] in a proc-macro crate.library/core/src/macros/mod.rs.These definitions exist to allow the macros to participate in typical path-based resolution - they can be imported, re-exported, and renamed just like any other item definition. However, the body of the definition is empty. Instead, the macro is annotated with the #[rustc_builtin_macro] attribute, which tells the compiler to run a corresponding function in rustc_builtin_macros.
All non-builtin attributes have the following characteristics:
#[derive] works without an import.