about summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-05-28 08:45:52 +0200
committerGitHub <noreply@github.com>2022-05-28 08:45:52 +0200
commit7e7dd1c0698187f54b2c3b36e8e3db1b67d3b2c4 (patch)
treefaa7d38ed03cd7bc729f121b6234c04a106dd14b /compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
parent880d3ea3c22dbdfdcaa288ac2b60fb1126bb828d (diff)
parentce9901fcee396764aaea7b1bce3f82b1b4f554d2 (diff)
downloadrust-7e7dd1c0698187f54b2c3b36e8e3db1b67d3b2c4.tar.gz
rust-7e7dd1c0698187f54b2c3b36e8e3db1b67d3b2c4.zip
Rollup merge of #97327 - davidtwco:diagnostic-translation-compile-time-validation, r=oli-obk
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..

```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...

```text
error: could not parse Fluent resource
  --> $DIR/test.rs:35:28
   |
LL |         missing_message => "./missing-message.ftl",
   |                            ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: see additional errors emitted

error: expected a message field for "missing-message"
 --> ./missing-message.ftl:1:1
  |
1 | missing-message =
  | ^^^^^^^^^^^^^^^^^^
  |
```
...or generating the following code if it succeeds:

```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:

```rust
let mut err = sess.struct_span_err(
    span,
    fluent::typeck::field_multiply_specified_in_initializer
);
err.span_label(
    span,
    fluent::typeck::field_multiply_specified_in_initializer_label
);
err.span_label(
    previous_use_span,
    fluent::typeck::field_multiply_specified_in_initializer_label_previous_use
);
err.emit();
```

I'd like to reduce the verbosity of referring to labels/notes/helps with this scheme (though it wasn't much better before), but I'll leave that for a follow-up.

r? `@oli-obk`
cc `@pvdrz` `@compiler-errors`
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp')
0 files changed, 0 insertions, 0 deletions