Home Explore Blog CI



rustc

5th chunk of `src/diagnostics/diagnostic-structs.md`
d208034c70d9cd4e11a090c251005b7d0fb737477223fba50000000100000acc
Like `Diagnostic`, `Subdiagnostic` supports `Option<T>` and
`Vec<T>` fields.

Suggestions can be emitted using one of four attributes on the type/variant:

- `#[suggestion(..., code = "...", applicability = "...")]`
- `#[suggestion_hidden(..., code = "...", applicability = "...")]`
- `#[suggestion_short(..., code = "...", applicability = "...")]`
- `#[suggestion_verbose(..., code = "...", applicability = "...")]`

Suggestions require `#[primary_span]` be set on a field and can have the
following sub-attributes:

- The first positional argument specifies the path to a item in
  `rustc_errors::fluent` corresponding to the Fluent attribute with the message
  and defaults to the equivalent of `.suggestion`.
- `code` specifies the code that should be suggested as a replacement and is a
  format string (e.g. `{field_name}` would be replaced by the value of the
  `field_name` field of the struct), not a Fluent identifier.
- `applicability` can be used to specify the applicability in the attribute, it
  cannot be used when the field's type contains an `Applicability`.

Applicabilities can also be specified as a field (of type `Applicability`)
using the `#[applicability]` attribute.

In the end, the `Subdiagnostic` derive will generate an implementation
of `Subdiagnostic` that looks like the following:

```rust
impl<'tcx> Subdiagnostic for ExpectedReturnTypeLabel<'tcx> {
    fn add_to_diag(self, diag: &mut rustc_errors::Diagnostic) {
        use rustc_errors::{Applicability, IntoDiagArg};
        match self {
            ExpectedReturnTypeLabel::Unit { span } => {
                diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_default_return_type)
            }
            ExpectedReturnTypeLabel::Other { span, expected } => {
                diag.set_arg("expected", expected);
                diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_return_type)
            }
        }
    }
}
```

Once defined, a subdiagnostic can be used by passing it to the `subdiagnostic`
function ([example][subdiag_use_1] and [example][subdiag_use_2]) on a
diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a
diagnostic struct.

### Reference
`#[derive(Subdiagnostic)]` supports the following attributes:

- `#[label(slug)]`, `#[help(slug)]`, `#[warning(slug)]` or `#[note(slug)]`
  - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
  - _Mandatory_
  - Defines the type to be representing a label, help or note.
  - Slug (_Mandatory_)
    - Uniquely identifies the diagnostic and corresponds to its Fluent message,
      mandatory.
    - A path to an item in `rustc_errors::fluent`, e.g.
      `rustc_errors::fluent::hir_analysis_field_already_declared`

Title: `Subdiagnostic` Implementation and Attributes Reference
Summary
This section continues explaining `Subdiagnostic`, particularly its support for `Option<T>` and `Vec<T>` fields, and the various suggestion attributes (`#[suggestion]`, `#[suggestion_hidden]`, `#[suggestion_short]`, `#[suggestion_verbose]`) along with their sub-attributes like 'code' and 'applicability'. It shows an example of the generated `Subdiagnostic` implementation and how to use subdiagnostics. The section concludes with a reference listing the supported attributes for `#[derive(Subdiagnostic)]`, including `#[label]`, `#[help]`, `#[warning]`, and `#[note]`, emphasizing the mandatory 'slug' parameter and its purpose.