diff options
Diffstat (limited to '')
-rw-r--r-- | src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md | 147 |
1 files changed, 76 insertions, 71 deletions
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index f456474c7..d51e79348 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -1,14 +1,14 @@ # Diagnostic and subdiagnostic structs rustc has two diagnostic derives that can be used to create simple diagnostics, which are recommended to be used when they are applicable: -`#[derive(SessionDiagnostic)]` and `#[derive(SessionSubdiagnostic)]`. +`#[derive(Diagnostic)]` and `#[derive(Subdiagnostic)]`. Diagnostics created with the derive macros can be translated into different languages and each has a slug that uniquely identifies the diagnostic. -## `#[derive(SessionDiagnostic)]` +## `#[derive(Diagnostic)]` Instead of using the `DiagnosticBuilder` API to create and emit diagnostics, -the `SessionDiagnostic` derive can be used. `#[derive(SessionDiagnostic)]` is +the `Diagnostic` derive can be used. `#[derive(Diagnostic)]` is only applicable for simple diagnostics that don't require much logic in deciding whether or not to add additional subdiagnostics. @@ -16,24 +16,24 @@ Consider the [definition][defn] of the "field already declared" diagnostic shown below: ```rust,ignore -#[derive(SessionDiagnostic)] -#[diag(typeck::field_already_declared, code = "E0124")] +#[derive(Diagnostic)] +#[diag(hir_analysis_field_already_declared, code = "E0124")] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_decl_label)] + #[label(hir_analysis_previous_decl_label)] pub prev_span: Span, } ``` -`SessionDiagnostic` can only be applied to structs. Every `SessionDiagnostic` +`Diagnostic` can only be applied to structs. Every `Diagnostic` has to have one attribute, `#[diag(...)]`, applied to the struct itself. If an error has an error code (e.g. "E0624"), then that can be specified using the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are -porting a diagnostic that uses `DiagnosticBuilder` to use `SessionDiagnostic` +porting a diagnostic that uses `DiagnosticBuilder` to use `Diagnostic` then you should keep the code if there was one. `#[diag(..)]` must provide a slug as the first positional argument (a path to an @@ -47,16 +47,16 @@ In our example, the Fluent message for the "field already declared" diagnostic looks like this: ```fluent -typeck_field_already_declared = +hir_analysis_field_already_declared = field `{$field_name}` is already declared .label = field already declared .previous_decl_label = `{$field_name}` first declared here ``` -`typeck_field_already_declared` is the slug from our example and is followed +`hir_analysis_field_already_declared` is the slug from our example and is followed by the diagnostic message. -Every field of the `SessionDiagnostic` which does not have an annotation is +Every field of the `Diagnostic` which does not have an annotation is available in Fluent messages as a variable, like `field_name` in the example above. Fields can be annotated `#[skip_arg]` if this is undesired. @@ -66,19 +66,19 @@ of the diagnostic. Diagnostics are more than just their primary message, they often include labels, notes, help messages and suggestions, all of which can also be -specified on a `SessionDiagnostic`. +specified on a `Diagnostic`. `#[label]`, `#[help]` and `#[note]` can all be applied to fields which have the type `Span`. Applying any of these attributes will create the corresponding subdiagnostic with that `Span`. These attributes will look for their diagnostic message in a Fluent attribute attached to the primary Fluent message. In our example, `#[label]` will look for -`typeck_field_already_declared.label` (which has the message "field already +`hir_analysis_field_already_declared.label` (which has the message "field already declared"). If there is more than one subdiagnostic of the same type, then these attributes can also take a value that is the attribute name to look for (e.g. `previous_decl_label` in our example). -Other types have special behavior when used in a `SessionDiagnostic` derive: +Other types have special behavior when used in a `Diagnostic` derive: - Any attribute applied to an `Option<T>` and will only emit a subdiagnostic if the option is `Some(..)`. @@ -107,21 +107,21 @@ 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`. -In the end, the `SessionDiagnostic` derive will generate an implementation of -`SessionDiagnostic` that looks like the following: +In the end, the `Diagnostic` derive will generate an implementation of +`IntoDiagnostic` that looks like the following: ```rust,ignore -impl SessionDiagnostic<'_> for FieldAlreadyDeclared { - fn into_diagnostic(self, sess: &'_ rustc_session::Session) -> DiagnosticBuilder<'_> { - let mut diag = sess.struct_err(rustc_errors::fluent::typeck::field_already_declared); +impl IntoDiagnostic<'_> for FieldAlreadyDeclared { + fn into_diagnostic(self, handler: &'_ rustc_errors::Handler) -> DiagnosticBuilder<'_> { + let mut diag = handler.struct_err(rustc_errors::fluent::hir_analysis_field_already_declared); diag.set_span(self.span); diag.span_label( self.span, - rustc_errors::fluent::typeck::label + rustc_errors::fluent::hir_analysis_label ); diag.span_label( self.prev_span, - rustc_errors::fluent::typeck::previous_decl_label + rustc_errors::fluent::hir_analysis_previous_decl_label ); diag } @@ -141,22 +141,20 @@ tcx.sess.emit_err(FieldAlreadyDeclared { ``` ### Reference -`#[derive(SessionDiagnostic)]` and `#[derive(LintDiagnostic)]` support the +`#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the following attributes: - `#[diag(slug, code = "...")]` - - _Applied to struct._ + - _Applied to struct or enum variant._ - _Mandatory_ - Defines the text and error code to be associated with the diagnostic. - Slug (_Mandatory_) - Uniquely identifies the diagnostic and corresponds to its Fluent message, mandatory. - - A path to an item in `rustc_errors::fluent`. Always in a module starting - with a Fluent resource name (which is typically the name of the crate - that the diagnostic is from), e.g. - `rustc_errors::fluent::typeck::field_already_declared` + - A path to an item in `rustc_errors::fluent`, e.g. + `rustc_errors::fluent::hir_analysis_field_already_declared` (`rustc_errors::fluent` is implicit in the attribute, so just - `typeck::field_already_declared`). + `hir_analysis_field_already_declared`). - See [translation documentation](./translation.md). - `code = "..."` (_Optional_) - Specifies the error code. @@ -191,14 +189,12 @@ following attributes: - _Applied to `(Span, MachineApplicability)` or `Span` fields._ - Adds a suggestion subdiagnostic. - Slug (_Mandatory_) - - A path to an item in `rustc_errors::fluent`. Always in a module starting - with a Fluent resource name (which is typically the name of the crate - that the diagnostic is from), e.g. - `rustc_errors::fluent::typeck::field_already_declared` + - A path to an item in `rustc_errors::fluent`, e.g. + `rustc_errors::fluent::hir_analysis_field_already_declared` (`rustc_errors::fluent` is implicit in the attribute, so just - `typeck::field_already_declared`). Fluent attributes for all messages - exist as top-level items in that module (so `typeck_message.attr` is just - `typeck::attr`). + `hir_analysis_field_already_declared`). Fluent attributes for all messages + exist as top-level items in that module (so `hir_analysis_message.attr` is just + `attr`). - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). @@ -210,20 +206,20 @@ following attributes: `has-placeholders` or `unspecified`. - `#[subdiagnostic]` - _Applied to a type that implements `AddToDiagnostic` (from - `#[derive(SessionSubdiagnostic)]`)._ + `#[derive(Subdiagnostic)]`)._ - Adds the subdiagnostic represented by the subdiagnostic struct. - `#[primary_span]` (_Optional_) - - _Applied to `Span` fields on `SessionSubdiagnostic`s. Not used for `LintDiagnostic`s._ + - _Applied to `Span` fields on `Subdiagnostic`s. Not used for `LintDiagnostic`s._ - Indicates the primary span of the diagnostic. - `#[skip_arg]` (_Optional_) - _Applied to any field._ - Prevents the field from being provided as a diagnostic argument. -## `#[derive(SessionSubdiagnostic)]` +## `#[derive(Subdiagnostic)]` It is common in the compiler to write a function that conditionally adds a specific subdiagnostic to an error if it is applicable. Oftentimes these subdiagnostics could be represented using a diagnostic struct even if the -overall diagnostic could not. In this circumstance, the `SessionSubdiagnostic` +overall diagnostic could not. In this circumstance, the `Subdiagnostic` derive can be used to represent a partial diagnostic (e.g a note, label, help or suggestion) as a struct. @@ -231,14 +227,14 @@ Consider the [definition][subdiag_defn] of the "expected return type" label shown below: ```rust -#[derive(SessionSubdiagnostic)] +#[derive(Subdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(typeck::expected_default_return_type)] + #[label(hir_analysis_expected_default_return_type)] Unit { #[primary_span] span: Span, }, - #[label(typeck::expected_return_type)] + #[label(hir_analysis_expected_return_type)] Other { #[primary_span] span: Span, @@ -247,9 +243,9 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } ``` -Unlike `SessionDiagnostic`, `SessionSubdiagnostic` can be applied to structs or +Unlike `Diagnostic`, `Subdiagnostic` can be applied to structs or enums. Attributes that are placed on the type for structs are placed on each -variants for enums (or vice versa). Each `SessionSubdiagnostic` should have one +variants for enums (or vice versa). Each `Subdiagnostic` should have one attribute applied to the struct or each variant, one of: - `#[label(..)]` for defining a label @@ -268,9 +264,9 @@ In our example, the Fluent message for the "expected return type" label looks like this: ```fluent -typeck_expected_default_return_type = expected `()` because of default return type +hir_analysis_expected_default_return_type = expected `()` because of default return type -typeck_expected_return_type = expected `{$expected}` because of return type +hir_analysis_expected_return_type = expected `{$expected}` because of return type ``` Using the `#[primary_span]` attribute on a field (with type `Span`) will denote @@ -281,7 +277,7 @@ Every field of the type/variant which does not have an annotation is available in Fluent messages as a variable. Fields can be annotated `#[skip_arg]` if this is undesired. -Like `SessionDiagnostic`, `SessionSubdiagnostic` supports `Option<T>` and +Like `Diagnostic`, `Subdiagnostic` supports `Option<T>` and `Vec<T>` fields. Suggestions can be emitted using one of four attributes on the type/variant: @@ -306,8 +302,8 @@ following sub-attributes: Applicabilities can also be specified as a field (of type `Applicability`) using the `#[applicability]` attribute. -In the end, the `SessionSubdiagnostic` derive will generate an implementation -of `SessionSubdiagnostic` that looks like the following: +In the end, the `Subdiagnostic` derive will generate an implementation +of `AddToDiagnostic` that looks like the following: ```rust impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> { @@ -315,11 +311,11 @@ impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> { use rustc_errors::{Applicability, IntoDiagnosticArg}; match self { ExpectedReturnTypeLabel::Unit { span } => { - diag.span_label(span, rustc_errors::fluent::typeck::expected_default_return_type) + 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::typeck::expected_return_type) + diag.span_label(span, rustc_errors::fluent::hir_analysis_expected_return_type) } } @@ -333,7 +329,7 @@ diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a diagnostic struct. ### Reference -`#[derive(SessionSubdiagnostic)]` supports the following attributes: +`#[derive(Subdiagnostic)]` supports the following attributes: - `#[label(slug)]`, `#[help(slug)]` or `#[note(slug)]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ @@ -342,26 +338,22 @@ diagnostic struct. - Slug (_Mandatory_) - Uniquely identifies the diagnostic and corresponds to its Fluent message, mandatory. - - A path to an item in `rustc_errors::fluent`. Always in a module starting - with a Fluent resource name (which is typically the name of the crate - that the diagnostic is from), e.g. - `rustc_errors::fluent::typeck::field_already_declared` + - A path to an item in `rustc_errors::fluent`, e.g. + `rustc_errors::fluent::hir_analysis_field_already_declared` (`rustc_errors::fluent` is implicit in the attribute, so just - `typeck::field_already_declared`). + `hir_analysis_field_already_declared`). - See [translation documentation](./translation.md). - `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]` - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ - _Mandatory_ - Defines the type to be representing a suggestion. - Slug (_Mandatory_) - - A path to an item in `rustc_errors::fluent`. Always in a module starting - with a Fluent resource name (which is typically the name of the crate - that the diagnostic is from), e.g. - `rustc_errors::fluent::typeck::field_already_declared` + - A path to an item in `rustc_errors::fluent`, e.g. + `rustc_errors::fluent::hir_analysis_field_already_declared` (`rustc_errors::fluent` is implicit in the attribute, so just - `typeck::field_already_declared`). Fluent attributes for all messages - exist as top-level items in that module (so `typeck_message.attr` is just - `typeck::attr`). + `hir_analysis::field_already_declared`). Fluent attributes for all messages + exist as top-level items in that module (so `hir_analysis_message.attr` is just + `hir_analysis::attr`). - See [translation documentation](./translation.md). - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or - `.suggestion` in Fluent). @@ -376,19 +368,32 @@ diagnostic struct. - `maybe-incorrect` - `has-placeholders` - `unspecified` -- `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise) +- `#[multipart_suggestion{,_hidden,_short,_verbose}(slug, applicability = "...")]` + - _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._ + - _Mandatory_ + - Defines the type to be representing a multipart suggestion. + - Slug (_Mandatory_): see `#[suggestion]` + - `applicability = "..."` (_Optional_): see `#[suggestion]` +- `#[primary_span]` (_Mandatory_ for labels and suggestions; _optional_ otherwise; not applicable +to multipart suggestions) - _Applied to `Span` fields._ - Indicates the primary span of the subdiagnostic. -- `#[applicability]` (_Optional_; only applicable to suggestions) +- `#[suggestion_part(code = "...")]` (_Mandatory_; only applicable to multipart suggestions) + - _Applied to `Span` fields._ + - Indicates the span to be one part of the multipart suggestion. + - `code = "..."` (_Mandatory_) + - Value is a format string indicating the code to be suggested as a + replacement. +- `#[applicability]` (_Optional_; only applicable to (simple and multipart) suggestions) - _Applied to `Applicability` fields._ - Indicates the applicability of the suggestion. - `#[skip_arg]` (_Optional_) - _Applied to any field._ - Prevents the field from being provided as a diagnostic argument. -[defn]: https://github.com/rust-lang/rust/blob/bbe9d27b8ff36da56638aa43d6d0cdfdf89a4e57/compiler/rustc_typeck/src/errors.rs#L65-L74 -[use]: https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/compiler/rustc_typeck/src/collect.rs#L981-L985 +[defn]: https://github.com/rust-lang/rust/blob/6201eabde85db854c1ebb57624be5ec699246b50/compiler/rustc_hir_analysis/src/errors.rs#L68-L77 +[use]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/collect.rs#L823-L827 -[subdiag_defn]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/errors.rs#L220-L233 -[subdiag_use_1]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L556-L560 -[subdiag_use_2]: https://github.com/rust-lang/rust/blob/e70c60d34b9783a2fd3171d88d248c2e0ec8ecdd/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs#L575-L579 +[subdiag_defn]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/errors.rs#L221-L234 +[subdiag_use_1]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs#L670-L674 +[subdiag_use_2]: https://github.com/rust-lang/rust/blob/f1112099eba41abadb6f921df7edba70affe92c5/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs#L704-L707 |