Crate rustc_attr_parsing

Source
Expand description

Centralized logic for parsing and attributes.

§Architecture

This crate is part of a series of crates that handle attribute processing.

The separation between data structures and parsing follows the principle of separation of concerns. Data structures (rustc_attr_data_structures) 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(...)]: Expands into trait implementations
  • #[cfg()]: Expands based on configuration
  • #[cfg_attr()]: 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()]: Marks stable API items
  • #[inline()]: Suggests function inlining
  • #[repr()]: 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, #[stable(...)] and #[unstable()] 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 produce 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.

Modules§

attributes 🔒
This module defines traits for attribute parsers, little state machines that recognize and parse attributes out of a longer list of attributes. The main trait is called AttributeParser. You can find more docs about AttributeParsers on the trait itself. However, for many types of attributes, implementing AttributeParser is not necessary. It allows for a lot of flexibility you might not want.
context 🔒
lints 🔒
parser
This is in essence an (improved) duplicate of rustc_ast/attr/mod.rs. That module is intended to be deleted in its entirety.
session_diagnostics 🔒

Structs§

AttributeParser
Context created once, for example as part of the ast lowering context, through which all attributes can be lowered.
Condition
Early
used when parsing attributes for miscelaneous things before ast lowering
Late
used when parsing attributes during ast lowering

Enums§

OmitDoc

Statics§

DEFAULT_LOCALE_RESOURCE
Raw content of Fluent resource for this crate, generated by fluent_messages macro, imported by rustc_driver to include all crates’ resources in one bundle.

Traits§

CfgMatchesLintEmitter
Emitter of a builtin lint from cfg_matches.

Functions§

cfg_matches
Tests if a cfg-pattern matches the cfg set
emit_attribute_lint
eval_condition
Evaluate a cfg-like condition (with any and all), using eval to evaluate individual items.
find_crate_name
is_builtin_attr
is_doc_alias_attrs_contain_symbol
parse_version
Parse a rustc version number written inside string literal in an attribute, like appears in since = "1.0.0". Suffixes like “-dev” and “-nightly” are not accepted in this position, unlike when parsing CFG_RELEASE.