Crate rustc_attr_parsing

Source
Expand description

Centralized logic for parsing and attributes.

Part of a series of crates:

  • rustc_attr_data_structures: contains types that the parsers parse into
  • rustc_attr_parsing: this crate
  • (in the future): rustc_attr_validation

History: Check out #131229. There used to be only one definition of attributes in the compiler: ast::Attribute. These were then parsed or validated or both in places distributed all over the compiler. This was a mess…

Attributes are markers on items. Many of them are actually attribute-like proc-macros, and are expanded to some other rust syntax. This could either be a user provided proc macro, or something compiler provided. derive is an example of one that the compiler provides. These are built-in, but they have a valid expansion to Rust tokens and are thus called “active”. I personally like calling these active compiler-provided attributes, built-in macros, because they still expand, and this helps to differentiate them from built-in attributes. However, I’ll be the first to admit that the naming here can be confusing.

The alternative to active attributes, are inert attributes. These can occur in user code (proc-macro helper attributes). But what’s important is, many built-in attributes are inert like this. There is nothing they expand to during the macro expansion process, sometimes because they literally cannot expand to something that is valid Rust. They are really just markers to guide the compilation process. An example is #[inline(...)] which changes how code for functions is generated.

                     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)     │
             │                      │ ]                    │
             │                      │                      │
             │                      │                      │
             │                      │                      │
             └──────────────────────┴──────────────────────┘

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.

As a rule of thumb, when a syntactical attribute can be applied more than once, they should be combined into a single semantic attribute. For example:

#[repr(C)]
#[repr(packed)]
struct Meow {}

should result in a single AttributeKind::Repr containing a list of repr annotations, in this case C and packed. This is equivalent to writing #[repr(C, packed)] in a single syntactical annotation.

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

Macros§

find_attr
Finds attributes in sequences of attributes by pattern matching.

Structs§

AttributeParser
Context created once, for example as part of the ast lowering context, through which all attributes can be lowered.
Condition
ConstStability
Represents the #[rustc_const_unstable] and #[rustc_const_stable] attributes.
DefaultBodyStability
Represents the #[rustc_default_body_unstable] attribute.
Deprecation
PartialConstStability
Excludes const_stable_indirect. This is necessary because when -Zforce-unstable-if-unmarked is set, we need to encode standalone #[rustc_const_stable_indirect] attributes
RustcVersion
Stability
Represents the following attributes:

Enums§

AttributeKind
Represent parsed, built in, inert attributes.
DeprecatedSince
Release in which an API is deprecated.
DiagnosticAttribute
InlineAttr
InstructionSetAttr
IntType
OmitDoc
OptimizeAttr
ReprAttr
StabilityLevel
The available stability levels.
StableSince
Rust release in which a feature is stabilized.
TransparencyError
UnstableReason

Constants§

VERSION_PLACEHOLDER
The version placeholder that recently stabilized features contain inside the since field of the #[stable] attribute.

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§

HashStableContext
Requirements for a StableHashingContext to be used in this crate. This is a hack to allow using the HashStable_Generic derive macro instead of implementing everything in rustc_middle.
PrintAttribute
This trait is used to print attributes in rustc_hir_pretty.

Functions§

cfg_matches
Tests if a cfg-pattern matches the cfg set
eval_condition
Evaluate a cfg-like condition (with any and all), using eval to evaluate individual items.
find_crate_name
is_builtin_attr
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.