11# Diagnostic and subdiagnostic structs
22rustc has two diagnostic derives that can be used to create simple diagnostics,
33which are recommended to be used when they are applicable:
4- ` #[derive(SessionDiagnostic )] ` and ` #[derive(SessionSubdiagnostic )] ` .
4+ ` #[derive(Diagnostic )] ` and ` #[derive(Subdiagnostic )] ` .
55
66Diagnostics created with the derive macros can be translated into different
77languages and each has a slug that uniquely identifies the diagnostic.
88
9- ## ` #[derive(SessionDiagnostic )] `
9+ ## ` #[derive(Diagnostic )] `
1010Instead 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
1212only applicable for simple diagnostics that don't require much logic in
1313deciding whether or not to add additional subdiagnostics.
1414
1515Consider the [ definition] [ defn ] of the "field already declared" diagnostic
1616shown below:
1717
1818``` rust,ignore
19- #[derive(SessionDiagnostic )]
19+ #[derive(Diagnostic )]
2020#[diag(typeck::field_already_declared, code = "E0124")]
2121pub struct FieldAlreadyDeclared {
2222 pub field_name: Ident,
@@ -28,12 +28,12 @@ pub struct FieldAlreadyDeclared {
2828}
2929```
3030
31- ` SessionDiagnostic ` can only be applied to structs. Every ` SessionDiagnostic `
31+ ` Diagnostic ` can only be applied to structs. Every ` Diagnostic `
3232has to have one attribute, ` #[diag(...)] ` , applied to the struct itself.
3333
3434If an error has an error code (e.g. "E0624"), then that can be specified using
3535the ` 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 `
3737then you should keep the code if there was one.
3838
3939` #[diag(..)] ` must provide a slug as the first positional argument (a path to an
@@ -56,7 +56,7 @@ typeck_field_already_declared =
5656` typeck_field_already_declared ` is the slug from our example and is followed
5757by the diagnostic message.
5858
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
6060available in Fluent messages as a variable, like ` field_name ` in the example
6161above. Fields can be annotated ` #[skip_arg] ` if this is undesired.
6262
@@ -66,7 +66,7 @@ of the diagnostic.
6666
6767Diagnostics are more than just their primary message, they often include
6868labels, notes, help messages and suggestions, all of which can also be
69- specified on a ` SessionDiagnostic ` .
69+ specified on a ` Diagnostic ` .
7070
7171` #[label] ` , ` #[help] ` and ` #[note] ` can all be applied to fields which have the
7272type ` 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
7878these attributes can also take a value that is the attribute name to look for
7979(e.g. ` previous_decl_label ` in our example).
8080
81- Other types have special behavior when used in a ` SessionDiagnostic ` derive:
81+ Other types have special behavior when used in a ` Diagnostic ` derive:
8282
8383- Any attribute applied to an ` Option<T> ` and will only emit a
8484 subdiagnostic if the option is ` Some(..) ` .
@@ -107,13 +107,13 @@ the value of the `field_name` field of the struct), not a Fluent identifier.
107107` applicability ` can be used to specify the applicability in the attribute, it
108108cannot be used when the field's type contains an ` Applicability ` .
109109
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:
112112
113113``` 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);
117117 diag.set_span(self.span);
118118 diag.span_label(
119119 self.span,
@@ -141,7 +141,7 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
141141```
142142
143143### Reference
144- ` #[derive(SessionDiagnostic )] ` and ` #[derive(LintDiagnostic)] ` support the
144+ ` #[derive(Diagnostic )] ` and ` #[derive(LintDiagnostic)] ` support the
145145following attributes:
146146
147147- ` #[diag(slug, code = "...")] `
@@ -210,28 +210,28 @@ following attributes:
210210 ` has-placeholders ` or ` unspecified ` .
211211- ` #[subdiagnostic] `
212212 - _ Applied to a type that implements ` AddToDiagnostic ` (from
213- ` #[derive(SessionSubdiagnostic )] ` )._
213+ ` #[derive(Subdiagnostic )] ` )._
214214 - Adds the subdiagnostic represented by the subdiagnostic struct.
215215- ` #[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._
217217 - Indicates the primary span of the diagnostic.
218218- ` #[skip_arg] ` (_ Optional_ )
219219 - _ Applied to any field._
220220 - Prevents the field from being provided as a diagnostic argument.
221221
222- ## ` #[derive(SessionSubdiagnostic )] `
222+ ## ` #[derive(Subdiagnostic )] `
223223It is common in the compiler to write a function that conditionally adds a
224224specific subdiagnostic to an error if it is applicable. Oftentimes these
225225subdiagnostics 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 `
227227derive can be used to represent a partial diagnostic (e.g a note, label, help or
228228suggestion) as a struct.
229229
230230Consider the [ definition] [ subdiag_defn ] of the "expected return type" label
231231shown below:
232232
233233``` rust
234- #[derive(SessionSubdiagnostic )]
234+ #[derive(Subdiagnostic )]
235235pub enum ExpectedReturnTypeLabel <'tcx > {
236236 #[label(typeck:: expected_default_return_type)]
237237 Unit {
@@ -247,9 +247,9 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
247247}
248248```
249249
250- Unlike ` SessionDiagnostic ` , ` SessionSubdiagnostic ` can be applied to structs or
250+ Unlike ` Diagnostic ` , ` Subdiagnostic ` can be applied to structs or
251251enums. 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
253253attribute applied to the struct or each variant, one of:
254254
255255- ` #[label(..)] ` for defining a label
@@ -281,7 +281,7 @@ Every field of the type/variant which does not have an annotation is available
281281in Fluent messages as a variable. Fields can be annotated ` #[skip_arg] ` if this
282282is undesired.
283283
284- Like ` SessionDiagnostic ` , ` SessionSubdiagnostic ` supports ` Option<T> ` and
284+ Like ` Diagnostic ` , ` Subdiagnostic ` supports ` Option<T> ` and
285285` Vec<T> ` fields.
286286
287287Suggestions can be emitted using one of four attributes on the type/variant:
@@ -306,8 +306,8 @@ following sub-attributes:
306306Applicabilities can also be specified as a field (of type ` Applicability ` )
307307using the ` #[applicability] ` attribute.
308308
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:
311311
312312``` rust
313313impl <'tcx > AddToDiagnostic for ExpectedReturnTypeLabel <'tcx > {
@@ -333,7 +333,7 @@ diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a
333333diagnostic struct.
334334
335335### Reference
336- ` #[derive(SessionSubdiagnostic )] ` supports the following attributes:
336+ ` #[derive(Subdiagnostic )] ` supports the following attributes:
337337
338338- ` #[label(slug)] ` , ` #[help(slug)] ` or ` #[note(slug)] `
339339 - _ Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
0 commit comments