Expand description
Centralized logic for parsing and attributes.
§Architecture
This crate is part of a series of crates and modules that handle attribute processing.
rustc_attr_ir: Defines the data structures that store parsed attributesrustc_attr_parsing: This crate, handles the parsing of attributesrustc_passes::check_attrhandles attribute validation that cannot be done in this crate
The separation between data structures and parsing follows the principle of separation of concerns.
Data structures (rustc_attr_ir) define what attributes look like after parsing.
This crate (rustc_attr_parsing) handles how to convert raw tokens into those structures.
This split allows other parts of the compiler to use the data structures without needing
the parsing logic, making the codebase more modular and maintainable.
§Background
Previously, the compiler had a single attribute definition (ast::Attribute) with parsing and
validation scattered throughout the codebase. This was reorganized for better maintainability
(see #131229).
§Types of Attributes
In Rust, attributes are markers that can be attached to items. They come in two main categories.
§1. Active Attributes
These are attribute-like proc-macros that expand into other Rust code. They can be either user-defined or compiler-provided. Examples of compiler-provided active attributes:
#[derive(Debug)]: Expands into trait implementations#[cfg(target_os = "windows")]: Expands based on configuration#[cfg_attr(feature = "foo", test)]: Conditional attribute application
§2. Inert Attributes
These are pure markers that don’t expand into other code. They guide the compilation process. They can be user-defined (in proc-macro helpers) or built-in. Examples of built-in inert attributes:
#[stable(feature = "scoped_threads", since = "1.63.0")]: Marks stable API items#[inline(never)]: Suggests function inlining#[repr(C)]: Controls type representation
Active Inert
┌──────────────────────┬──────────────────────┐
│ (mostly in) │ these are parsed │
│ rustc_builtin_macros │ here! │
│ │ │
│ #[derive(...)] │ #[stable()] │
Built-in │ #[cfg()] │ #[inline()] │
│ #[cfg_attr()] │ #[repr()] │
│ │ │
├──────────────────────┼──────────────────────┤
│ │ │
│ │ `b` in │
│ │ #[proc_macro_derive( │
User created │ #[proc_macro_attr()] │ a, │
│ │ attributes(b) │
│ │ ] │
└──────────────────────┴──────────────────────┘§How This Crate Works
In this crate, syntactical attributes (sequences of tokens that look like
#[something(something else)]) are parsed into more semantic attributes, markers on items.
Multiple syntactic attributes might influence a single semantic attribute. For example,
the stable and unstable attributes cannot occur together, and both semantically define
a “stability” of an item. So, the stability attribute has an
AttributeParser that recognizes both the stable
and unstable syntactic attributes, and at the end produces a single
AttributeKind::Stability.
When multiple instances of the same attribute are allowed, they’re combined into a single semantic attribute. For example:
#[repr(C)]
#[repr(packed)]
struct Meow {}This is equivalent to #[repr(C, packed)] and results in a single AttributeKind::Repr
containing both C and packed annotations.
§Early attribute parsing
While lowering to the HIR, all attributes are parsed using the attribute parsers.
However, sometimes an attributes’ parsed form is needed before the HIR is constructed.
This is referred to as “early” attribute parsing,
and is performed using the parse_limited_* family of functions on AttributeParser.
Re-exports§
pub use attributes::AttributeSafety;pub use attributes::cfg::CFG_TEMPLATE;pub use attributes::cfg::EvalConfigResult;pub use attributes::cfg::eval_config_entry;pub use attributes::cfg::parse_cfg;pub use attributes::cfg::parse_cfg_attr;pub use attributes::cfg::parse_cfg_entry;pub use attributes::util::is_builtin_attr;pub use attributes::util::parse_version;pub use context::ShouldEmit;pub use diagnostics::ParsedDescription;pub use interface::AttributeParser;pub use interface::EmitAttribute;pub use template::AttributeTemplate;
Modules§
- attributes 🔒
- Traits for parsing attributes.
- check_
cfg 🔒 - context 🔒
- Context given to attribute parsers when parsing.
- diagnostics 🔒
- generated 🔒
- interface 🔒
- API for other crates to parse attributes themselves.
- parser
- Parsing of attribute arguments.
- safety 🔒
- stability 🔒
- synthetic 🔒
- target_
checking 🔒 - template 🔒
- validate_
attr - Meta-syntax validation logic of attributes for post-expansion.
Macros§
- template
- A convenience macro for constructing attribute templates.
E.g.,
template!(Word, List: "description")means that the attribute supports forms#[attr]and#[attr(description)]. - unstable