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
.
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.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.