
Revert <https://github.com/rust-lang/rust/pull/138084> to buy time to consider options that avoids breaking downstream usages of cargo on distributed `rustc-src` artifacts, where such cargo invocations fail due to inability to inherit `lints` from workspace root manifest's `workspace.lints` (this is only valid for the source rust-lang/rust workspace, but not really the distributed `rustc-src` artifacts). This breakage was reported in <https://github.com/rust-lang/rust/issues/138304>. This reverts commit48caf81484
, reversing changes made toc6662879b2
.
97 lines
5.2 KiB
Rust
97 lines
5.2 KiB
Rust
//! 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](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...
|
|
//!
|
|
//! 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.
|
|
//!
|
|
//! ```text
|
|
//! 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`](attributes::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.
|
|
|
|
// tidy-alphabetical-start
|
|
#![allow(internal_features)]
|
|
#![doc(rust_logo)]
|
|
#![feature(let_chains)]
|
|
#![feature(rustdoc_internals)]
|
|
#![warn(unreachable_pub)]
|
|
// tidy-alphabetical-end
|
|
|
|
#[macro_use]
|
|
mod attributes;
|
|
mod context;
|
|
pub mod parser;
|
|
mod session_diagnostics;
|
|
|
|
pub use attributes::cfg::*;
|
|
pub use attributes::util::{find_crate_name, is_builtin_attr, parse_version};
|
|
pub use context::{AttributeParser, OmitDoc};
|
|
pub use rustc_attr_data_structures::*;
|
|
|
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|