rust/compiler/rustc_macros/src/lib.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

135 lines
4.2 KiB
Rust
Raw Normal View History

#![feature(allow_internal_unstable)]
2022-11-13 12:10:36 +00:00
#![feature(if_let_guard)]
2023-01-08 23:00:41 +00:00
#![feature(let_chains)]
#![feature(never_type)]
#![feature(proc_macro_diagnostic)]
macros: introduce `fluent_messages` macro Adds a new `fluent_messages` macro which performs compile-time validation of the compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same messages) and generates constants that make using those messages in diagnostics more ergonomic. For example, given the following invocation of the macro.. ```ignore (rust) fluent_messages! { typeck => "./typeck.ftl", } ``` ..where `typeck.ftl` has the following contents.. ```fluent typeck-field-multiply-specified-in-initializer = field `{$ident}` specified more than once .label = used more than once .label-previous-use = first use of `{$ident}` ``` ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and will generate the following code: ```ignore (rust) pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[ include_str!("./typeck.ftl"), ]; mod fluent_generated { mod typeck { pub const field_multiply_specified_in_initializer: DiagnosticMessage = DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer"); pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage = DiagnosticMessage::fluent_attr( "typeck-field-multiply-specified-in-initializer", "previous-use-label" ); } } ``` When emitting a diagnostic, the generated constants can be used as follows: ```ignore (rust) let mut err = sess.struct_span_err( span, fluent::typeck::field_multiply_specified_in_initializer ); err.span_default_label(span); err.span_label( previous_use_span, fluent::typeck::field_multiply_specified_in_initializer_label_previous_use ); err.emit(); ``` Signed-off-by: David Wood <david.wood@huawei.com>
2022-05-23 17:24:55 +00:00
#![feature(proc_macro_span)]
#![feature(proc_macro_tracked_env)]
2019-08-11 16:55:14 +00:00
#![allow(rustc::default_hash_types)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
2023-08-22 11:06:38 +00:00
#![allow(internal_features)]
2019-04-05 11:11:44 +00:00
#![recursion_limit = "128"]
2019-03-05 18:27:50 +00:00
use synstructure::decl_derive;
2018-12-03 00:14:35 +00:00
2018-12-03 00:14:35 +00:00
use proc_macro::TokenStream;
2023-10-27 00:18:21 +00:00
mod current_version;
mod diagnostics;
2018-12-03 00:14:35 +00:00
mod hash_stable;
mod lift;
2018-12-03 00:14:35 +00:00
mod query;
mod serialize;
mod symbols;
2019-11-13 19:47:41 +00:00
mod type_foldable;
2022-06-17 09:53:29 +00:00
mod type_visitable;
2018-12-03 00:14:35 +00: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-27 00:18:21 +00:00
#[proc_macro]
pub fn current_rustc_version(input: TokenStream) -> TokenStream {
current_version::current_version(input)
}
2018-12-03 00:14:35 +00:00
#[proc_macro]
pub fn rustc_queries(input: TokenStream) -> TokenStream {
query::rustc_queries(input)
}
2018-12-03 00:14:35 +00:00
#[proc_macro]
pub fn symbols(input: TokenStream) -> TokenStream {
symbols::symbols(input.into()).into()
}
2018-12-16 03:44:12 +00:00
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
2019-11-09 19:34:55 +00:00
decl_derive!(
[HashStable_Generic, attributes(stable_hasher)] =>
hash_stable::hash_stable_generic_derive
);
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);
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
);
decl_derive!([Lift, attributes(lift)] => lift::lift_derive);
decl_derive!(
[Diagnostic, attributes(
// struct attributes
diag,
help,
note,
warning,
// field attributes
skip_arg,
primary_span,
label,
subdiagnostic,
suggestion,
suggestion_short,
suggestion_hidden,
suggestion_verbose)] => diagnostics::session_diagnostic_derive
);
decl_derive!(
[LintDiagnostic, attributes(
// struct attributes
diag,
help,
note,
warning,
// field attributes
skip_arg,
primary_span,
label,
subdiagnostic,
suggestion,
suggestion_short,
suggestion_hidden,
suggestion_verbose)] => diagnostics::lint_diagnostic_derive
);
decl_derive!(
[Subdiagnostic, attributes(
// struct/variant attributes
label,
help,
note,
warning,
suggestion,
suggestion_short,
suggestion_hidden,
suggestion_verbose,
multipart_suggestion,
multipart_suggestion_short,
multipart_suggestion_hidden,
multipart_suggestion_verbose,
// field attributes
skip_arg,
primary_span,
suggestion_part,
applicability)] => diagnostics::session_subdiagnostic_derive
);