rustc_macros/diagnostics/mod.rs
1mod diagnostic;
2mod diagnostic_builder;
3mod error;
4mod message;
5mod msg_macro;
6mod subdiagnostic;
7mod utils;
8
9use diagnostic::DiagnosticDerive;
10pub(super) use msg_macro::msg_macro;
11use proc_macro2::TokenStream;
12use subdiagnostic::SubdiagnosticDerive;
13use synstructure::Structure;
14
15/// Implements `#[derive(Diagnostic)]`, which allows for errors to be specified as a struct,
16/// independent from the actual diagnostics emitting code.
17///
18/// ```ignore (rust)
19/// # extern crate rustc_errors;
20/// # use rustc_errors::Applicability;
21/// # extern crate rustc_span;
22/// # use rustc_span::{Ident, Span};
23/// # extern crate rust_middle;
24/// # use rustc_middle::ty::Ty;
25/// #[derive(Diagnostic)]
26/// #[diag("this is an example message", code = E0123)]
27/// pub(crate) struct ExampleError<'tcx> {
28/// pub name: Ident,
29/// pub ty: Ty<'tcx>,
30/// #[primary_span]
31/// #[label("with a label")]
32/// pub span: Span,
33/// #[label("with a label")]
34/// pub other_span: Span,
35/// #[suggestion("with a suggestion", code = "{name}.clone()")]
36/// pub opt_sugg: Option<(Span, Applicability)>,
37/// }
38/// ```
39///
40/// Then, later, to emit the error:
41///
42/// ```ignore (rust)
43/// sess.emit_err(ExampleError {
44/// name, ty, span, other_span, opt_sugg
45/// });
46/// ```
47///
48/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
49/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
50pub(super) fn diagnostic_derive(s: Structure<'_>) -> TokenStream {
51 DiagnosticDerive::new(s).into_tokens()
52}
53
54/// Implements `#[derive(Subdiagnostic)]`, which allows for labels, notes, helps and
55/// suggestions to be specified as a structs or enums, independent from the actual diagnostics
56/// emitting code or diagnostic derives.
57///
58/// ```ignore (rust)
59/// #[derive(Subdiagnostic)]
60/// pub(crate) enum BuiltinUnusedDocCommentSub {
61/// #[help("use `//` for a plain comment")]
62/// PlainHelp,
63/// #[help("use `/* */` for a plain comment")]
64/// BlockHelp,
65/// }
66/// ```
67/// Then, later, use the subdiagnostic in a diagnostic:
68///
69/// ```ignore (rust)
70/// #[derive(Diagnostic)]
71/// #[diag("unused doc comment")]
72/// pub(crate) struct BuiltinUnusedDocComment<'a> {
73/// pub kind: &'a str,
74/// #[label("rustdoc does not generate documentation for {$kind}")]
75/// pub label: Span,
76/// #[subdiagnostic]
77/// pub sub: BuiltinUnusedDocCommentSub,
78/// }
79/// ```
80pub(super) fn subdiagnostic_derive(s: Structure<'_>) -> TokenStream {
81 SubdiagnosticDerive::new().into_tokens(s)
82}