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 🔒
Structs§
- Attribute
Parser - Context created once, for example as part of the ast lowering context, through which all attributes can be lowered.
- Condition
Enums§
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§
- CfgMatches
Lint Emitter - Emitter of a builtin lint from
cfg_matches
.
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 - 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.