Repository: rust-lang/rust
File: compiler/rustc_macros/src/diagnostics/mod.rs (Rust)

Code before:
mod diagnostic;
mod diagnostic_builder;
mod error;
mod message;
mod subdiagnostic;
mod utils;

use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
use proc_macro2::TokenStream;
use subdiagnostic::SubdiagnosticDerive;
use synstructure::Structure;

/// Implements `#[derive(Diagnostic)]`, which allows for errors to be specified as a struct,
/// independent from the actual diagnostics emitting code.
///
/// ```ignore (rust)
/// # extern crate rustc_errors;
/// # use rustc_errors::Applicability;
/// # extern crate rustc_span;
/// # use rustc_span::{Ident, Span};
/// # extern crate rust_middle;
/// # use rustc_middle::ty::Ty;
/// #[derive(Diagnostic)]
/// #[diag("this is an example message", code = E0123)]
/// struct ExampleError<'tcx> {
///     name: Ident,
///     ty: Ty<'tcx>,
///     #[primary_span]
///     #[label("with a label")]
///     span: Span,
///     #[label("with a label")]
///     other_span: Span,
///     #[suggestion("with a suggestion", code = "{name}.clone()")]
///     opt_sugg: Option<(Span, Applicability)>,
/// }
/// ```
///
/// Then, later, to emit the error:
///
/// ```ignore (rust)
/// sess.emit_err(ExampleError {
///     expected,
///     actual,
///     span,
///     first_borrow_span,
///     clone_sugg: Some(suggestion, Applicability::MachineApplicable),
/// });
/// ```
///
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:

Review comment (suggestion):
Error structs are almost always `pub(crate)` and their fields are almost always all `pub`. I think the example should reflect this.

Code after:
mod diagnostic;
mod diagnostic_builder;
mod error;
mod message;
mod subdiagnostic;
mod utils;

use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
use proc_macro2::TokenStream;
use subdiagnostic::SubdiagnosticDerive;
use synstructure::Structure;

/// Implements `#[derive(Diagnostic)]`, which allows for errors to be specified as a struct,
/// independent from the actual diagnostics emitting code.
///
/// ```ignore (rust)
/// # extern crate rustc_errors;
/// # use rustc_errors::Applicability;
/// # extern crate rustc_span;
/// # use rustc_span::{Ident, Span};
/// # extern crate rust_middle;
/// # use rustc_middle::ty::Ty;
/// #[derive(Diagnostic)]
/// #[diag("this is an example message", code = E0123)]
/// pub(crate) struct ExampleError<'tcx> {
///     pub name: Ident,
///     pub ty: Ty<'tcx>,
///     #[primary_span]
///     #[label("with a label")]
///     pub span: Span,
///     #[label("with a label")]
///     pub other_span: Span,
///     #[suggestion("with a suggestion", code = "{name}.clone()")]
///     pub opt_sugg: Option<(Span, Applicability)>,
/// }
/// ```
///
/// Then, later, to emit the error:
///
/// ```ignore (rust)
/// sess.emit_err(ExampleError {
///     name, ty, span, other_span, opt_sugg
/// });
/// ```
///
/// See rustc dev guide for more examples on using the `#[derive(Diagnostic)]`:
/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
pub(super) fn diagnostic_derive(s: Structure<'_>) -> TokenStream {
    DiagnosticDerive::new(s).into_tokens()
}