Rollup merge of #142058 - xizheyin:rustc-attr-parsing, r=jdonszelmann
Clean `rustc_attr_parsing/src/lib.rs` documentation Improves the documentation clarity in `rustc_attr_parsing` by restructuring content with clearer section headers, simplifying explanations of attribute types, making technical descriptions more precise. r? ``@oli-obk``
This commit is contained in:
@@ -74,7 +74,7 @@ pub(crate) trait AttributeParser: Default + 'static {
|
||||
pub(crate) trait SingleAttributeParser: 'static {
|
||||
const PATH: &'static [Symbol];
|
||||
|
||||
/// Caled when a duplicate attribute is found.
|
||||
/// Called when a duplicate attribute is found.
|
||||
///
|
||||
/// `first_span` is the span of the first occurrence of this attribute.
|
||||
// FIXME(jdonszelmann): default error
|
||||
|
||||
@@ -1,31 +1,38 @@
|
||||
//! 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
|
||||
//! ## Architecture
|
||||
//! This crate is part of a series of crates that handle attribute processing.
|
||||
//! - [rustc_attr_data_structures](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_data_structures/index.html): Defines the data structures that store parsed attributes
|
||||
//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes
|
||||
//! - (planned) rustc_attr_validation: Will handle attribute validation
|
||||
//!
|
||||
//! History: Check out [#131229](https://github.com/rust-lang/rust/issues/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...
|
||||
//! 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.
|
||||
//!
|
||||
//! 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.
|
||||
//! ## 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](https://github.com/rust-lang/rust/issues/131229)).
|
||||
//!
|
||||
//! 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.
|
||||
//! ## 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
|
||||
//!
|
||||
//! ```text
|
||||
//! Active Inert
|
||||
@@ -33,27 +40,21 @@
|
||||
//! │ (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,
|
||||
@@ -63,18 +64,17 @@
|
||||
//! and `#[unstable()]` syntactic attributes, and at the end produce a single
|
||||
//! [`AttributeKind::Stability`](rustc_attr_data_structures::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:
|
||||
//! When multiple instances of the same attribute are allowed, they're combined into a single
|
||||
//! semantic attribute. For example:
|
||||
//!
|
||||
//! ```
|
||||
//! ```rust
|
||||
//! #[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.
|
||||
//! This is equivalent to `#[repr(C, packed)]` and results in a single `AttributeKind::Repr`
|
||||
//! containing both `C` and `packed` annotations.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
|
||||
Reference in New Issue
Block a user