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 aboutAttributeParser
s on the trait itself. However, for many types of attributes, implementingAttributeParser
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§
- Attribute
Parser - Context created once, for example as part of the ast lowering context, through which all attributes can be lowered.
- Condition
- Const
Stability - Represents the
#[rustc_const_unstable]
and#[rustc_const_stable]
attributes. - Default
Body Stability - Represents the
#[rustc_default_body_unstable]
attribute. - Deprecation
- Partial
Const Stability - 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 - Rustc
Version - Stability
- Represents the following attributes:
Enums§
- Attribute
Kind - Represent parsed, built in, inert attributes.
- Deprecated
Since - Release in which an API is deprecated.
- Diagnostic
Attribute - Inline
Attr - Instruction
SetAttr - IntType
- OmitDoc
- Optimize
Attr - Repr
Attr - Stability
Level - The available stability levels.
- Stable
Since - Rust release in which a feature is stabilized.
- Transparency
Error - Unstable
Reason
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 byrustc_driver
to include all crates’ resources in one bundle.
Traits§
- Hash
Stable Context - Requirements for a
StableHashingContext
to be used in this crate. This is a hack to allow using theHashStable_Generic
derive macro instead of implementing everything inrustc_middle
. - Print
Attribute - 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
andall
), usingeval
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.