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