11# Diagnostic and subdiagnostic structs
2- rustc has three diagnostic traits that can be used to create diagnostics:
3- ` Diagnostic ` , ` LintDiagnostic ` , and ` Subdiagnostic ` .
2+ rustc has two diagnostic traits that can be used to create diagnostics:
3+ ` Diagnostic ` and ` Subdiagnostic ` .
44
55For simple diagnostics,
66derived impls can be used, e.g. ` #[derive(Diagnostic)] ` . They are only suitable for simple diagnostics that
7- don't require much logic in deciding whether or not to add additional
8- subdiagnostics.
7+ don't require much logic in deciding whether or not to add additional subdiagnostics.
98
109In cases where diagnostics require more complex or dynamic behavior, such as conditionally adding subdiagnostics,
1110customizing the rendering logic, or selecting messages at runtime, you will need to manually implement
12- the corresponding trait (` Diagnostic ` , ` LintDiagnostic ` , or ` Subdiagnostic ` ).
11+ the corresponding trait (` Diagnostic ` or ` Subdiagnostic ` ).
1312This approach provides greater flexibility and is recommended for diagnostics that go beyond simple, static structures.
1413
1514Diagnostic can be translated into different languages.
1615
17- ## ` #[derive(Diagnostic)] ` and ` #[derive(LintDiagnostic)] `
16+ ## ` #[derive(Diagnostic)] `
1817
19- Consider the [ definition] [ defn ] of the "field already declared" diagnostic
20- shown below:
18+ Consider the [ definition] [ defn ] of the "field already declared" diagnostic shown below:
2119
2220``` rust,ignore
2321#[derive(Diagnostic)]
@@ -32,47 +30,47 @@ pub struct FieldAlreadyDeclared {
3230}
3331```
3432
35- ` Diagnostic ` can only be derived on structs and enums.
33+ ` Diagnostic ` can only be derived on structs and enums.
3634Attributes that are placed on the type for structs are placed on each
37- variants for enums (or vice versa). Each ` Diagnostic ` has to have one
35+ variants for enums (or vice versa).
36+ Each ` Diagnostic ` has to have one
3837attribute, ` #[diag(...)] ` , applied to the struct or each enum variant.
3938
4039If an error has an error code (e.g. "E0624"), then that can be specified using
41- the ` code ` sub-attribute. Specifying a ` code ` isn't mandatory, but if you are
40+ the ` code ` sub-attribute.
41+ Specifying a ` code ` isn't mandatory, but if you are
4242porting a diagnostic that uses ` Diag ` to use ` Diagnostic `
4343then you should keep the code if there was one.
4444
45- ` #[diag(..)] ` must provide a message as the first positional argument.
46- The message is written in English, but might be translated to the locale requested by the user. See
47- [ translation documentation] ( ./translation.md ) to learn more about how
45+ ` #[diag(..)] ` must provide a message as the first positional argument.
46+ The message is written in English, but might be translated to the locale requested by the user.
47+ See [ translation documentation] ( ./translation.md ) to learn more about how
4848translatable error messages are written and how they are generated.
4949
5050Every field of the ` Diagnostic ` which does not have an annotation is
51- available in Fluent messages as a variable, like ` field_name ` in the example
52- above. Fields can be annotated ` #[skip_arg] ` if this is undesired.
51+ available in Fluent messages as a variable, like ` field_name ` in the example above.
52+ Fields can be annotated ` #[skip_arg] ` if this is undesired.
5353
5454Using the ` #[primary_span] ` attribute on a field (that has type ` Span ` )
55- indicates the primary span of the diagnostic which will have the main message
56- of the diagnostic.
55+ indicates the primary span of the diagnostic which will have the main message of the diagnostic.
5756
5857Diagnostics are more than just their primary message, they often include
59- labels, notes, help messages and suggestions, all of which can also be
60- specified on a ` Diagnostic ` .
58+ labels, notes, help messages and suggestions, all of which can also be specified on a ` Diagnostic ` .
6159
6260` #[label] ` , ` #[help] ` , ` #[warning] ` and ` #[note] ` can all be applied to fields which have the
63- type ` Span ` . Applying any of these attributes will create the corresponding
64- subdiagnostic with that ` Span ` . These attributes take a diagnostic message as an argument.
61+ type ` Span ` .
62+ Applying any of these attributes will create the corresponding subdiagnostic with that ` Span ` .
63+ These attributes take a diagnostic message as an argument.
6564
6665Other types have special behavior when used in a ` Diagnostic ` derive:
6766
6867- Any attribute applied to an ` Option<T> ` will only emit a
6968 subdiagnostic if the option is ` Some(..) ` .
70- - Any attribute applied to a ` Vec<T> ` will be repeated for each element of the
71- vector.
69+ - Any attribute applied to a ` Vec<T> ` will be repeated for each element of the vector.
7270
7371` #[help] ` , ` #[warning] ` and ` #[note] ` can also be applied to the struct itself, in which case
74- they work exactly like when applied to fields except the subdiagnostic won't
75- have a ` Span ` . These attributes can also be applied to fields of type ` () ` for
72+ they work exactly like when applied to fields except the subdiagnostic won't have a ` Span ` .
73+ These attributes can also be applied to fields of type ` () ` for
7674the same effect, which when combined with the ` Option ` type can be used to
7775represent optional ` #[note] ` /` #[help] ` /` #[warning] ` subdiagnostics.
7876
@@ -84,8 +82,8 @@ Suggestions can be emitted using one of four field attributes:
8482- ` #[suggestion_verbose("message", code = "...", applicability = "...")] `
8583
8684Suggestions must be applied on either a ` Span ` field or a `(Span,
87- MachineApplicability)` field. Similarly to other field attributes, a message
88- needs to be provided which will be shown to the user.
85+ MachineApplicability)` field.
86+ Similarly to other field attributes, a message needs to be provided which will be shown to the user.
8987` code ` specifies the code that should be suggested as a
9088replacement and is a format string (e.g. ` {field_name} ` would be replaced by
9189the value of the ` field_name ` field of the struct).
@@ -113,8 +111,8 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a> for FieldAlreadyDeclared {
113111}
114112```
115113
116- Now that we've defined our diagnostic, how do we [ use it] [ use ] ? It's quite
117- straightforward, just create an instance of the struct and pass it to
114+ Now that we've defined our diagnostic, how do we [ use it] [ use ] ?
115+ It's quite straightforward, just create an instance of the struct and pass it to
118116` emit_err ` (or ` emit_warning ` ):
119117
120118``` rust,ignore
@@ -125,9 +123,8 @@ tcx.dcx().emit_err(FieldAlreadyDeclared {
125123});
126124```
127125
128- ### Reference for ` #[derive(Diagnostic)] ` and ` #[derive(LintDiagnostic)] `
129- ` #[derive(Diagnostic)] ` and ` #[derive(LintDiagnostic)] ` support the
130- following attributes:
126+ ### Reference for ` #[derive(Diagnostic)] `
127+ ` #[derive(Diagnostic)] ` supports the following attributes:
131128
132129- ` #[diag("message", code = "...")] `
133130 - _ Applied to struct or enum variant._
@@ -164,32 +161,31 @@ following attributes:
164161 - Value is the suggestion message that will be shown to the user.
165162 - See [ translation documentation] ( ./translation.md ) .
166163 - ` code = "..." ` /` code("...", ...) ` (_ Mandatory_ )
167- - One or multiple format strings indicating the code to be suggested as a
168- replacement. Multiple values signify multiple possible replacements.
164+ - One or multiple format strings indicating the code to be suggested as a replacement.
165+ Multiple values signify multiple possible replacements.
169166 - ` applicability = "..." ` (_ Optional_ )
170167 - String which must be one of ` machine-applicable ` , ` maybe-incorrect ` ,
171168 ` has-placeholders ` or ` unspecified ` .
172169- ` #[subdiagnostic] `
173- - _ Applied to a type that implements ` Subdiagnostic ` (from
174- ` #[derive(Subdiagnostic)] ` )._
170+ - _ Applied to a type that implements ` Subdiagnostic ` (from ` #[derive(Subdiagnostic)] ` )._
175171 - Adds the subdiagnostic represented by the subdiagnostic struct.
176172- ` #[primary_span] ` (_ Optional_ )
177- - _ Applied to ` Span ` fields on ` Subdiagnostic ` s. Not used for ` LintDiagnostic ` s. _
173+ - _ Applied to ` Span ` fields on ` Subdiagnostic ` s.
178174 - Indicates the primary span of the diagnostic.
179175- ` #[skip_arg] ` (_ Optional_ )
180176 - _ Applied to any field._
181177 - Prevents the field from being provided as a diagnostic argument.
182178
183179## ` #[derive(Subdiagnostic)] `
184180It is common in the compiler to write a function that conditionally adds a
185- specific subdiagnostic to an error if it is applicable. Oftentimes these
186- subdiagnostics could be represented using a diagnostic struct even if the
187- overall diagnostic could not. In this circumstance, the ` Subdiagnostic `
181+ specific subdiagnostic to an error if it is applicable.
182+ Oftentimes these subdiagnostics could be represented using a diagnostic struct even if the
183+ overall diagnostic could not.
184+ In this circumstance, the ` Subdiagnostic `
188185derive can be used to represent a partial diagnostic (e.g a note, label, help or
189186suggestion) as a struct.
190187
191- Consider the [ definition] [ subdiag_defn ] of the "expected return type" label
192- shown below:
188+ Consider the [ definition] [ subdiag_defn ] of the "expected return type" label shown below:
193189
194190``` rust
195191#[derive(Subdiagnostic )]
@@ -208,10 +204,10 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
208204}
209205```
210206
211- Like ` Diagnostic ` , ` Subdiagnostic ` can be derived for structs or
212- enums. Attributes that are placed on the type for structs are placed on each
213- variants for enums (or vice versa). Each ` Subdiagnostic ` should have one
214- attribute applied to the struct or each variant, one of:
207+ Like ` Diagnostic ` , ` Subdiagnostic ` can be derived for structs or enums.
208+ Attributes that are placed on the type for structs are placed on each
209+ variants for enums (or vice versa).
210+ Each ` Subdiagnostic ` should have one attribute applied to the struct or each variant, one of:
215211
216212- ` #[label(..)] ` for defining a label
217213- ` #[note(..)] ` for defining a note
@@ -224,15 +220,14 @@ See [translation documentation](./translation.md) to learn more about how
224220translatable error messages are generated.
225221
226222Using the ` #[primary_span] ` attribute on a field (with type ` Span ` ) will denote
227- the primary span of the subdiagnostic. A primary span is only necessary for a
228- label or suggestion, which can not be spanless.
223+ the primary span of the subdiagnostic.
224+ A primary span is only necessary for a label or suggestion, which can not be spanless.
229225
230226Every field of the type/variant which does not have an annotation is available
231- in Fluent messages as a variable. Fields can be annotated ` #[skip_arg] ` if this
232- is undesired.
227+ in Fluent messages as a variable.
228+ Fields can be annotated ` #[skip_arg] ` if this is undesired.
233229
234- Like ` Diagnostic ` , ` Subdiagnostic ` supports ` Option<T> ` and
235- ` Vec<T> ` fields.
230+ Like ` Diagnostic ` , ` Subdiagnostic ` supports ` Option<T> ` and ` Vec<T> ` fields.
236231
237232Suggestions can be emitted using one of four attributes on the type/variant:
238233
@@ -241,8 +236,7 @@ Suggestions can be emitted using one of four attributes on the type/variant:
241236- ` #[suggestion_short("...", code = "...", applicability = "...")] `
242237- ` #[suggestion_verbose("...", code = "...", applicability = "...")] `
243238
244- Suggestions require ` #[primary_span] ` be set on a field and can have the
245- following sub-attributes:
239+ Suggestions require ` #[primary_span] ` be set on a field and can have the following sub-attributes:
246240
247241- The first positional argument specifies the message which will be shown to the user.
248242- ` code ` specifies the code that should be suggested as a replacement and is a
@@ -276,8 +270,7 @@ impl<'tcx> Subdiagnostic for ExpectedReturnTypeLabel<'tcx> {
276270
277271Once defined, a subdiagnostic can be used by passing it to the ` subdiagnostic `
278272function ([ example] [ subdiag_use_1 ] and [ example] [ subdiag_use_2 ] ) on a
279- diagnostic or by assigning it to a ` #[subdiagnostic] ` -annotated field of a
280- diagnostic struct.
273+ diagnostic or by assigning it to a ` #[subdiagnostic] ` -annotated field of a diagnostic struct.
281274
282275### Argument sharing and isolation
283276
@@ -310,22 +303,24 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with
310303` #[derive(Subdiagnostic)] ` supports the following attributes:
311304
312305- ` #[label("message")] ` , ` #[help("message")] ` , ` #[warning("message")] ` or ` #[note("message")] `
313- - _ Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
306+ - _ Applied to struct or enum variant.
307+ Mutually exclusive with struct/enum variant attributes._
314308 - _ Mandatory_
315309 - Defines the type to be representing a label, help or note.
316310 - Message (_ Mandatory_ )
317311 - The diagnostic message that will be shown to the user.
318312 - See [ translation documentation] ( ./translation.md ) .
319313- ` #[suggestion{,_hidden,_short,_verbose}("message", code = "...", applicability = "...")] `
320- - _ Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
314+ - _ Applied to struct or enum variant.
315+ Mutually exclusive with struct/enum variant attributes._
321316 - _ Mandatory_
322317 - Defines the type to be representing a suggestion.
323318 - Message (_ Mandatory_ )
324319 - The diagnostic message that will be shown to the user.
325320 - See [ translation documentation] ( ./translation.md ) .
326321 - ` code = "..." ` /` code("...", ...) ` (_ Mandatory_ )
327- - One or multiple format strings indicating the code to be suggested as a
328- replacement. Multiple values signify multiple possible replacements.
322+ - One or multiple format strings indicating the code to be suggested as a replacement.
323+ Multiple values signify multiple possible replacements.
329324 - ` applicability = "..." ` (_ Optional_ )
330325 - _ Mutually exclusive with ` #[applicability] ` on a field._
331326 - Value is the applicability of the suggestion.
@@ -335,7 +330,8 @@ Additionally, subdiagnostics can access arguments from the main diagnostic with
335330 - ` has-placeholders `
336331 - ` unspecified `
337332- ` #[multipart_suggestion{,_hidden,_short,_verbose}("message", applicability = "...")] `
338- - _ Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
333+ - _ Applied to struct or enum variant.
334+ Mutually exclusive with struct/enum variant attributes._
339335 - _ Mandatory_
340336 - Defines the type to be representing a multipart suggestion.
341337 - Message (_ Mandatory_ ): see ` #[suggestion] `
@@ -348,8 +344,7 @@ to multipart suggestions)
348344 - _ Applied to ` Span ` fields._
349345 - Indicates the span to be one part of the multipart suggestion.
350346 - ` code = "..." ` (_ Mandatory_ )
351- - Value is a format string indicating the code to be suggested as a
352- replacement.
347+ - Value is a format string indicating the code to be suggested as a replacement.
353348- ` #[applicability] ` (_ Optional_ ; only applicable to (simple and multipart) suggestions)
354349 - _ Applied to ` Applicability ` fields._
355350 - Indicates the applicability of the suggestion.
0 commit comments