Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
2024-06-12 13:49:36 +10:00
|
|
|
// tidy-alphabetical-start
|
|
|
|
#![allow(rustc::default_hash_types)]
|
2022-11-13 13:10:36 +01:00
|
|
|
#![feature(if_let_guard)]
|
2023-01-09 00:00:41 +01:00
|
|
|
#![feature(let_chains)]
|
2022-05-07 06:02:11 +01:00
|
|
|
#![feature(never_type)]
|
2022-04-26 11:59:45 +01:00
|
|
|
#![feature(proc_macro_diagnostic)]
|
2022-05-23 18:24:55 +01:00
|
|
|
#![feature(proc_macro_span)]
|
2023-10-25 11:20:07 -07:00
|
|
|
#![feature(proc_macro_tracked_env)]
|
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
2024-06-12 13:49:36 +10:00
|
|
|
// tidy-alphabetical-end
|
2019-04-05 13:11:44 +02:00
|
|
|
|
2018-12-03 01:14:35 +01:00
|
|
|
use proc_macro::TokenStream;
|
2024-07-29 08:13:50 +10:00
|
|
|
use synstructure::decl_derive;
|
2018-12-03 01:14:35 +01:00
|
|
|
|
2023-10-26 17:18:21 -07:00
|
|
|
mod current_version;
|
2022-04-27 02:57:44 +01:00
|
|
|
mod diagnostics;
|
2024-02-13 23:49:28 +00:00
|
|
|
mod extension;
|
2018-12-03 01:14:35 +01:00
|
|
|
mod hash_stable;
|
2019-11-14 23:31:49 +01:00
|
|
|
mod lift;
|
2025-02-09 22:50:03 +01:00
|
|
|
mod print_attribute;
|
2018-12-03 01:14:35 +01:00
|
|
|
mod query;
|
2020-06-11 15:49:57 +01:00
|
|
|
mod serialize;
|
2019-04-03 02:43:49 +02:00
|
|
|
mod symbols;
|
2024-10-25 18:22:03 +11:00
|
|
|
mod try_from;
|
2019-12-22 17:42:04 -05:00
|
|
|
mod type_foldable;
|
2022-06-17 10:53:29 +01:00
|
|
|
mod type_visitable;
|
2018-12-03 01:14:35 +01:00
|
|
|
|
2023-11-08 17:05:44 +11:00
|
|
|
// Reads the rust version (e.g. "1.75.0") from the CFG_RELEASE env var and
|
|
|
|
// produces a `RustcVersion` literal containing that version (e.g.
|
|
|
|
// `RustcVersion { major: 1, minor: 75, patch: 0 }`).
|
2023-10-26 17:18:21 -07:00
|
|
|
#[proc_macro]
|
|
|
|
pub fn current_rustc_version(input: TokenStream) -> TokenStream {
|
|
|
|
current_version::current_version(input)
|
|
|
|
}
|
|
|
|
|
2018-12-03 01:14:35 +01:00
|
|
|
#[proc_macro]
|
|
|
|
pub fn rustc_queries(input: TokenStream) -> TokenStream {
|
|
|
|
query::rustc_queries(input)
|
|
|
|
}
|
2018-12-03 01:14:35 +01:00
|
|
|
|
2019-04-03 02:43:49 +02:00
|
|
|
#[proc_macro]
|
|
|
|
pub fn symbols(input: TokenStream) -> TokenStream {
|
Improve error handling in `symbols` proc-macro
This improves how the `symbols` proc-macro handles errors.
If it finds an error in its input, the macro does not panic.
Instead, it still produces an output token stream. That token
stream will contain `compile_error!(...)` macro invocations.
This will still cause compilation to fail (which is what we want),
but it will prevent meaningless errors caused by the output not
containing symbols that the macro normally generates.
This solves a small (but annoying) problem. When you're editing
rustc_span/src/symbol.rs, and you get something wrong (dup
symbol name, misordered symbol), you want to get only the errors
that are relevant, not a burst of errors that are irrelevant.
This change also uses the correct Span when reporting errors,
so you get errors that point to the correct place in
rustc_span/src/symbol.rs where something is wrong.
This also adds several unit tests which test the `symbols` proc-macro.
This commit also makes it easy to run the `symbols` proc-macro
as an ordinary Cargo test. Just run `cargo test`. This makes it
easier to do development on the macro itself, such as running it
under a debugger.
This commit also uses the `Punctuated` type in `syn` for parsing
comma-separated lists, rather than doing it manually.
The output of the macro is not changed at all by this commit,
so rustc should be completely unchanged. This just improves
quality of life during development.
2020-12-11 11:32:48 -08:00
|
|
|
symbols::symbols(input.into()).into()
|
2022-02-09 17:24:51 -05:00
|
|
|
}
|
|
|
|
|
2024-02-19 16:07:39 +00:00
|
|
|
/// Derive an extension trait for a given impl block. The trait name
|
|
|
|
/// goes into the parenthesized args of the macro, for greppability.
|
|
|
|
/// For example:
|
|
|
|
/// ```
|
|
|
|
/// use rustc_macros::extension;
|
|
|
|
/// #[extension(pub trait Foo)]
|
|
|
|
/// impl i32 { fn hello() {} }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// expands to:
|
|
|
|
/// ```
|
|
|
|
/// pub trait Foo { fn hello(); }
|
|
|
|
/// impl Foo for i32 { fn hello() {} }
|
|
|
|
/// ```
|
2024-02-13 23:49:28 +00:00
|
|
|
#[proc_macro_attribute]
|
2024-02-14 17:18:56 +00:00
|
|
|
pub fn extension(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|
|
|
extension::extension(attr, input)
|
2024-02-13 23:49:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-16 04:44:12 +01:00
|
|
|
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
|
2019-11-09 20:34:55 +01:00
|
|
|
decl_derive!(
|
|
|
|
[HashStable_Generic, attributes(stable_hasher)] =>
|
|
|
|
hash_stable::hash_stable_generic_derive
|
|
|
|
);
|
2023-11-04 17:02:54 +00:00
|
|
|
decl_derive!(
|
|
|
|
[HashStable_NoContext] =>
|
|
|
|
/// `HashStable` implementation that has no `HashStableContext` bound and
|
|
|
|
/// which adds `where` bounds for `HashStable` based off of fields and not
|
|
|
|
/// generics. This is suitable for use in crates like `rustc_type_ir`.
|
|
|
|
hash_stable::hash_stable_no_context_derive
|
|
|
|
);
|
2019-11-09 20:34:55 +01:00
|
|
|
|
2025-03-13 17:36:33 +00:00
|
|
|
decl_derive!([Decodable_NoContext] => serialize::decodable_nocontext_derive);
|
|
|
|
decl_derive!([Encodable_NoContext] => serialize::encodable_nocontext_derive);
|
2020-06-11 15:49:57 +01:00
|
|
|
decl_derive!([Decodable] => serialize::decodable_derive);
|
|
|
|
decl_derive!([Encodable] => serialize::encodable_derive);
|
|
|
|
decl_derive!([TyDecodable] => serialize::type_decodable_derive);
|
|
|
|
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
|
|
|
|
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
|
|
|
|
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
|
2023-02-14 00:01:37 +00:00
|
|
|
decl_derive!(
|
|
|
|
[TypeFoldable, attributes(type_foldable)] =>
|
|
|
|
/// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported).
|
|
|
|
///
|
|
|
|
/// The fold will produce a value of the same struct or enum variant as the input, with
|
|
|
|
/// each field respectively folded using the `TypeFoldable` implementation for its type.
|
|
|
|
/// However, if a field of a struct or an enum variant is annotated with
|
|
|
|
/// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its
|
|
|
|
/// type is not required to implement `TypeFoldable`).
|
|
|
|
type_foldable::type_foldable_derive
|
|
|
|
);
|
|
|
|
decl_derive!(
|
|
|
|
[TypeVisitable, attributes(type_visitable)] =>
|
|
|
|
/// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported).
|
|
|
|
///
|
|
|
|
/// Each field of the struct or enum variant will be visited in definition order, using the
|
|
|
|
/// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum
|
|
|
|
/// variant is annotated with `#[type_visitable(ignore)]` then that field will not be
|
|
|
|
/// visited (and its type is not required to implement `TypeVisitable`).
|
|
|
|
type_visitable::type_visitable_derive
|
|
|
|
);
|
2019-11-14 23:31:49 +01:00
|
|
|
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
|
2020-08-27 20:00:21 +10:00
|
|
|
decl_derive!(
|
2022-09-18 11:46:56 -04:00
|
|
|
[Diagnostic, attributes(
|
2022-03-31 08:35:17 +01:00
|
|
|
// struct attributes
|
2022-08-19 15:02:10 +02:00
|
|
|
diag,
|
2022-03-31 12:10:00 +01:00
|
|
|
help,
|
2024-04-24 17:28:26 +00:00
|
|
|
help_once,
|
2022-07-11 18:46:24 +01:00
|
|
|
note,
|
2024-04-24 17:28:26 +00:00
|
|
|
note_once,
|
2022-08-24 17:57:10 +02:00
|
|
|
warning,
|
2022-03-31 08:35:17 +01:00
|
|
|
// field attributes
|
2022-03-31 09:02:31 +01:00
|
|
|
skip_arg,
|
2022-03-31 08:50:45 +01:00
|
|
|
primary_span,
|
2020-08-27 20:00:21 +10:00
|
|
|
label,
|
2022-04-27 05:59:48 +01:00
|
|
|
subdiagnostic,
|
2020-08-27 20:00:21 +10:00
|
|
|
suggestion,
|
|
|
|
suggestion_short,
|
|
|
|
suggestion_hidden,
|
2024-03-08 12:13:39 +11:00
|
|
|
suggestion_verbose)] => diagnostics::diagnostic_derive
|
2020-08-27 20:00:21 +10:00
|
|
|
);
|
2022-06-30 08:57:45 +01:00
|
|
|
decl_derive!(
|
|
|
|
[LintDiagnostic, attributes(
|
|
|
|
// struct attributes
|
2022-08-19 15:02:10 +02:00
|
|
|
diag,
|
2022-06-30 08:57:45 +01:00
|
|
|
help,
|
2024-04-24 17:28:26 +00:00
|
|
|
help_once,
|
2022-07-11 18:46:24 +01:00
|
|
|
note,
|
2024-04-24 17:28:26 +00:00
|
|
|
note_once,
|
2022-08-24 17:57:10 +02:00
|
|
|
warning,
|
2022-06-30 08:57:45 +01:00
|
|
|
// field attributes
|
|
|
|
skip_arg,
|
|
|
|
primary_span,
|
|
|
|
label,
|
|
|
|
subdiagnostic,
|
|
|
|
suggestion,
|
|
|
|
suggestion_short,
|
|
|
|
suggestion_hidden,
|
|
|
|
suggestion_verbose)] => diagnostics::lint_diagnostic_derive
|
|
|
|
);
|
2022-04-26 11:59:45 +01:00
|
|
|
decl_derive!(
|
2022-09-18 11:47:31 -04:00
|
|
|
[Subdiagnostic, attributes(
|
2022-04-26 11:59:45 +01:00
|
|
|
// struct/variant attributes
|
|
|
|
label,
|
|
|
|
help,
|
2024-04-24 17:28:26 +00:00
|
|
|
help_once,
|
2022-04-26 11:59:45 +01:00
|
|
|
note,
|
2024-04-24 17:28:26 +00:00
|
|
|
note_once,
|
2022-08-24 17:57:10 +02:00
|
|
|
warning,
|
2024-04-20 12:52:05 +00:00
|
|
|
subdiagnostic,
|
2022-04-26 11:59:45 +01:00
|
|
|
suggestion,
|
|
|
|
suggestion_short,
|
|
|
|
suggestion_hidden,
|
|
|
|
suggestion_verbose,
|
2022-08-23 07:54:06 +02:00
|
|
|
multipart_suggestion,
|
|
|
|
multipart_suggestion_short,
|
|
|
|
multipart_suggestion_hidden,
|
|
|
|
multipart_suggestion_verbose,
|
2022-04-26 11:59:45 +01:00
|
|
|
// field attributes
|
|
|
|
skip_arg,
|
|
|
|
primary_span,
|
2022-08-23 07:54:06 +02:00
|
|
|
suggestion_part,
|
2024-03-08 12:13:39 +11:00
|
|
|
applicability)] => diagnostics::subdiagnostic_derive
|
2022-04-26 11:59:45 +01:00
|
|
|
);
|
2024-10-25 18:22:03 +11:00
|
|
|
|
|
|
|
decl_derive! {
|
|
|
|
[TryFromU32] =>
|
|
|
|
/// Derives `TryFrom<u32>` for the annotated `enum`, which must have no fields.
|
|
|
|
/// Each variant maps to the value it would produce under an `as u32` cast.
|
|
|
|
///
|
|
|
|
/// The error type is `u32`.
|
|
|
|
try_from::try_from_u32
|
|
|
|
}
|
2025-02-09 22:50:03 +01:00
|
|
|
decl_derive! {
|
|
|
|
[PrintAttribute] =>
|
|
|
|
/// Derives `PrintAttribute` for `AttributeKind`.
|
|
|
|
/// This macro is pretty specific to `rustc_attr_data_structures` and likely not that useful in
|
|
|
|
/// other places. It's deriving something close to `Debug` without printing some extraenous
|
|
|
|
/// things like spans.
|
|
|
|
print_attribute::print_attribute
|
|
|
|
}
|