1
1
# Diagnostic and subdiagnostic structs
2
2
rustc has two diagnostic derives that can be used to create simple diagnostics,
3
3
which are recommended to be used when they are applicable:
4
- ` #[derive(SessionDiagnostic )] ` and ` #[derive(SessionSubdiagnostic )] ` .
4
+ ` #[derive(Diagnostic )] ` and ` #[derive(Subdiagnostic )] ` .
5
5
6
6
Diagnostics created with the derive macros can be translated into different
7
7
languages and each has a slug that uniquely identifies the diagnostic.
8
8
9
- ## ` #[derive(SessionDiagnostic )] `
9
+ ## ` #[derive(Diagnostic )] `
10
10
Instead of using the ` DiagnosticBuilder ` API to create and emit diagnostics,
11
- the ` SessionDiagnostic ` derive can be used. ` #[derive(SessionDiagnostic )] ` is
11
+ the ` Diagnostic ` derive can be used. ` #[derive(Diagnostic )] ` is
12
12
only applicable for simple diagnostics that don't require much logic in
13
13
deciding whether or not to add additional subdiagnostics.
14
14
15
15
Consider the [ definition] [ defn ] of the "field already declared" diagnostic
16
16
shown below:
17
17
18
18
``` rust,ignore
19
- #[derive(SessionDiagnostic )]
19
+ #[derive(Diagnostic )]
20
20
#[diag(typeck::field_already_declared, code = "E0124")]
21
21
pub struct FieldAlreadyDeclared {
22
22
pub field_name: Ident,
@@ -28,12 +28,12 @@ pub struct FieldAlreadyDeclared {
28
28
}
29
29
```
30
30
31
- ` SessionDiagnostic ` can only be applied to structs. Every ` SessionDiagnostic `
31
+ ` Diagnostic ` can only be applied to structs. Every ` Diagnostic `
32
32
has to have one attribute, ` #[diag(...)] ` , applied to the struct itself.
33
33
34
34
If an error has an error code (e.g. "E0624"), then that can be specified using
35
35
the ` code ` sub-attribute. Specifying a ` code ` isn't mandatory, but if you are
36
- porting a diagnostic that uses ` DiagnosticBuilder ` to use ` SessionDiagnostic `
36
+ porting a diagnostic that uses ` DiagnosticBuilder ` to use ` Diagnostic `
37
37
then you should keep the code if there was one.
38
38
39
39
` #[diag(..)] ` must provide a slug as the first positional argument (a path to an
@@ -56,7 +56,7 @@ typeck_field_already_declared =
56
56
` typeck_field_already_declared ` is the slug from our example and is followed
57
57
by the diagnostic message.
58
58
59
- Every field of the ` SessionDiagnostic ` which does not have an annotation is
59
+ Every field of the ` Diagnostic ` which does not have an annotation is
60
60
available in Fluent messages as a variable, like ` field_name ` in the example
61
61
above. Fields can be annotated ` #[skip_arg] ` if this is undesired.
62
62
@@ -66,7 +66,7 @@ of the diagnostic.
66
66
67
67
Diagnostics are more than just their primary message, they often include
68
68
labels, notes, help messages and suggestions, all of which can also be
69
- specified on a ` SessionDiagnostic ` .
69
+ specified on a ` Diagnostic ` .
70
70
71
71
` #[label] ` , ` #[help] ` and ` #[note] ` can all be applied to fields which have the
72
72
type ` Span ` . Applying any of these attributes will create the corresponding
@@ -78,7 +78,7 @@ declared"). If there is more than one subdiagnostic of the same type, then
78
78
these attributes can also take a value that is the attribute name to look for
79
79
(e.g. ` previous_decl_label ` in our example).
80
80
81
- Other types have special behavior when used in a ` SessionDiagnostic ` derive:
81
+ Other types have special behavior when used in a ` Diagnostic ` derive:
82
82
83
83
- Any attribute applied to an ` Option<T> ` and will only emit a
84
84
subdiagnostic if the option is ` Some(..) ` .
@@ -107,13 +107,13 @@ the value of the `field_name` field of the struct), not a Fluent identifier.
107
107
` applicability ` can be used to specify the applicability in the attribute, it
108
108
cannot be used when the field's type contains an ` Applicability ` .
109
109
110
- In the end, the ` SessionDiagnostic ` derive will generate an implementation of
111
- ` SessionDiagnostic ` that looks like the following:
110
+ In the end, the ` Diagnostic ` derive will generate an implementation of
111
+ ` IntoDiagnostic ` that looks like the following:
112
112
113
113
``` rust,ignore
114
- impl SessionDiagnostic <'_> for FieldAlreadyDeclared {
115
- fn into_diagnostic(self, sess : &'_ rustc_session::Session ) -> DiagnosticBuilder<'_> {
116
- let mut diag = sess .struct_err(rustc_errors::fluent::typeck::field_already_declared);
114
+ impl IntoDiagnostic <'_> for FieldAlreadyDeclared {
115
+ fn into_diagnostic(self, handler : &'_ rustc_errors::Handler ) -> DiagnosticBuilder<'_> {
116
+ let mut diag = handler .struct_err(rustc_errors::fluent::typeck::field_already_declared);
117
117
diag.set_span(self.span);
118
118
diag.span_label(
119
119
self.span,
@@ -141,7 +141,7 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
141
141
```
142
142
143
143
### Reference
144
- ` #[derive(SessionDiagnostic )] ` and ` #[derive(LintDiagnostic)] ` support the
144
+ ` #[derive(Diagnostic )] ` and ` #[derive(LintDiagnostic)] ` support the
145
145
following attributes:
146
146
147
147
- ` #[diag(slug, code = "...")] `
@@ -210,28 +210,28 @@ following attributes:
210
210
` has-placeholders ` or ` unspecified ` .
211
211
- ` #[subdiagnostic] `
212
212
- _ Applied to a type that implements ` AddToDiagnostic ` (from
213
- ` #[derive(SessionSubdiagnostic )] ` )._
213
+ ` #[derive(Subdiagnostic )] ` )._
214
214
- Adds the subdiagnostic represented by the subdiagnostic struct.
215
215
- ` #[primary_span] ` (_ Optional_ )
216
- - _ Applied to ` Span ` fields on ` SessionSubdiagnostic ` s. Not used for ` LintDiagnostic ` s._
216
+ - _ Applied to ` Span ` fields on ` Subdiagnostic ` s. Not used for ` LintDiagnostic ` s._
217
217
- Indicates the primary span of the diagnostic.
218
218
- ` #[skip_arg] ` (_ Optional_ )
219
219
- _ Applied to any field._
220
220
- Prevents the field from being provided as a diagnostic argument.
221
221
222
- ## ` #[derive(SessionSubdiagnostic )] `
222
+ ## ` #[derive(Subdiagnostic )] `
223
223
It is common in the compiler to write a function that conditionally adds a
224
224
specific subdiagnostic to an error if it is applicable. Oftentimes these
225
225
subdiagnostics could be represented using a diagnostic struct even if the
226
- overall diagnostic could not. In this circumstance, the ` SessionSubdiagnostic `
226
+ overall diagnostic could not. In this circumstance, the ` Subdiagnostic `
227
227
derive can be used to represent a partial diagnostic (e.g a note, label, help or
228
228
suggestion) as a struct.
229
229
230
230
Consider the [ definition] [ subdiag_defn ] of the "expected return type" label
231
231
shown below:
232
232
233
233
``` rust
234
- #[derive(SessionSubdiagnostic )]
234
+ #[derive(Subdiagnostic )]
235
235
pub enum ExpectedReturnTypeLabel <'tcx > {
236
236
#[label(typeck:: expected_default_return_type)]
237
237
Unit {
@@ -247,9 +247,9 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
247
247
}
248
248
```
249
249
250
- Unlike ` SessionDiagnostic ` , ` SessionSubdiagnostic ` can be applied to structs or
250
+ Unlike ` Diagnostic ` , ` Subdiagnostic ` can be applied to structs or
251
251
enums. Attributes that are placed on the type for structs are placed on each
252
- variants for enums (or vice versa). Each ` SessionSubdiagnostic ` should have one
252
+ variants for enums (or vice versa). Each ` Subdiagnostic ` should have one
253
253
attribute applied to the struct or each variant, one of:
254
254
255
255
- ` #[label(..)] ` for defining a label
@@ -281,7 +281,7 @@ Every field of the type/variant which does not have an annotation is available
281
281
in Fluent messages as a variable. Fields can be annotated ` #[skip_arg] ` if this
282
282
is undesired.
283
283
284
- Like ` SessionDiagnostic ` , ` SessionSubdiagnostic ` supports ` Option<T> ` and
284
+ Like ` Diagnostic ` , ` Subdiagnostic ` supports ` Option<T> ` and
285
285
` Vec<T> ` fields.
286
286
287
287
Suggestions can be emitted using one of four attributes on the type/variant:
@@ -306,8 +306,8 @@ following sub-attributes:
306
306
Applicabilities can also be specified as a field (of type ` Applicability ` )
307
307
using the ` #[applicability] ` attribute.
308
308
309
- In the end, the ` SessionSubdiagnostic ` derive will generate an implementation
310
- of ` SessionSubdiagnostic ` that looks like the following:
309
+ In the end, the ` Subdiagnostic ` derive will generate an implementation
310
+ of ` AddToDiagnostic ` that looks like the following:
311
311
312
312
``` rust
313
313
impl <'tcx > AddToDiagnostic for ExpectedReturnTypeLabel <'tcx > {
@@ -333,7 +333,7 @@ diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a
333
333
diagnostic struct.
334
334
335
335
### Reference
336
- ` #[derive(SessionSubdiagnostic )] ` supports the following attributes:
336
+ ` #[derive(Subdiagnostic )] ` supports the following attributes:
337
337
338
338
- ` #[label(slug)] ` , ` #[help(slug)] ` or ` #[note(slug)] `
339
339
- _ Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
0 commit comments