about summary refs log tree commit diff
path: root/compiler/rustc_macros/src/diagnostics/mod.rs
diff options
context:
space:
mode:
authorDavid Wood <david.wood@huawei.com>2022-05-23 18:24:55 +0100
committerDavid Wood <david.wood@huawei.com>2022-05-24 16:48:17 +0100
commit552eb3295a06a1a6841686f064647c4d847552cb (patch)
tree1bc88af0c4305db818c9f9172d081b9a05ae6ccf /compiler/rustc_macros/src/diagnostics/mod.rs
parent6e85efda2289b7b4b7f0b6ef876d3f8316dc2383 (diff)
downloadrust-552eb3295a06a1a6841686f064647c4d847552cb.tar.gz
rust-552eb3295a06a1a6841686f064647c4d847552cb.zip
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>
Diffstat (limited to 'compiler/rustc_macros/src/diagnostics/mod.rs')
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
1 files changed, 2 insertions, 0 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index ccd3880057b..69573d904d4 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -1,9 +1,11 @@
 mod diagnostic;
 mod error;
+mod fluent;
 mod subdiagnostic;
 mod utils;
 
 use diagnostic::SessionDiagnosticDerive;
+pub(crate) use fluent::fluent_messages;
 use proc_macro2::TokenStream;
 use quote::format_ident;
 use subdiagnostic::SessionSubdiagnosticDerive;