]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_macros/src/diagnostics/mod.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_macros / src / diagnostics / mod.rs
CommitLineData
04454e1e 1mod diagnostic;
064997fb 2mod diagnostic_builder;
04454e1e 3mod error;
923072b8 4mod fluent;
04454e1e
FG
5mod subdiagnostic;
6mod utils;
7
064997fb 8use diagnostic::{LintDiagnosticDerive, SessionDiagnosticDerive};
923072b8 9pub(crate) use fluent::fluent_messages;
04454e1e
FG
10use proc_macro2::TokenStream;
11use quote::format_ident;
12use subdiagnostic::SessionSubdiagnosticDerive;
13use synstructure::Structure;
14
15/// Implements `#[derive(SessionDiagnostic)]`, which allows for errors to be specified as a struct,
16/// independent from the actual diagnostics emitting code.
17///
923072b8 18/// ```ignore (rust)
04454e1e
FG
19/// # extern crate rustc_errors;
20/// # use rustc_errors::Applicability;
21/// # extern crate rustc_span;
22/// # use rustc_span::{symbol::Ident, Span};
23/// # extern crate rust_middle;
24/// # use rustc_middle::ty::Ty;
25/// #[derive(SessionDiagnostic)]
f2b60f7d 26/// #[diag(borrowck::move_out_of_borrow, code = "E0505")]
04454e1e
FG
27/// pub struct MoveOutOfBorrowError<'tcx> {
28/// pub name: Ident,
29/// pub ty: Ty<'tcx>,
30/// #[primary_span]
31/// #[label]
32/// pub span: Span,
064997fb 33/// #[label(borrowck::first_borrow_label)]
04454e1e
FG
34/// pub first_borrow_span: Span,
35/// #[suggestion(code = "{name}.clone()")]
36/// pub clone_sugg: Option<(Span, Applicability)>
37/// }
38/// ```
39///
40/// ```fluent
f2b60f7d 41/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
04454e1e 42/// .label = cannot move out of borrow
f2b60f7d 43/// .first_borrow_label = `{$ty}` first borrowed here
04454e1e
FG
44/// .suggestion = consider cloning here
45/// ```
46///
47/// Then, later, to emit the error:
48///
923072b8 49/// ```ignore (rust)
04454e1e
FG
50/// sess.emit_err(MoveOutOfBorrowError {
51/// expected,
52/// actual,
53/// span,
54/// first_borrow_span,
55/// clone_sugg: Some(suggestion, Applicability::MachineApplicable),
56/// });
57/// ```
58///
59/// See rustc dev guide for more examples on using the `#[derive(SessionDiagnostic)]`:
064997fb 60/// <https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html>
04454e1e 61pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
064997fb
FG
62 SessionDiagnosticDerive::new(format_ident!("diag"), format_ident!("sess"), s).into_tokens()
63}
04454e1e 64
064997fb
FG
65/// Implements `#[derive(LintDiagnostic)]`, which allows for lints to be specified as a struct,
66/// independent from the actual lint emitting code.
67///
68/// ```ignore (rust)
69/// #[derive(LintDiagnostic)]
f2b60f7d 70/// #[diag(lint::atomic_ordering_invalid_fail_success)]
064997fb
FG
71/// pub struct AtomicOrderingInvalidLint {
72/// method: Symbol,
73/// success_ordering: Symbol,
74/// fail_ordering: Symbol,
75/// #[label(lint::fail_label)]
76/// fail_order_arg_span: Span,
77/// #[label(lint::success_label)]
78/// #[suggestion(
79/// code = "std::sync::atomic::Ordering::{success_suggestion}",
80/// applicability = "maybe-incorrect"
81/// )]
82/// success_order_arg_span: Span,
83/// }
84/// ```
85///
86/// ```fluent
f2b60f7d
FG
87/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
88/// .fail_label = `{$fail_ordering}` failure ordering
89/// .success_label = `{$success_ordering}` success ordering
064997fb
FG
90/// .suggestion = consider using `{$success_suggestion}` success ordering instead
91/// ```
92///
93/// Then, later, to emit the error:
94///
95/// ```ignore (rust)
96/// cx.struct_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint {
97/// method,
98/// success_ordering,
99/// fail_ordering,
100/// fail_order_arg_span,
101/// success_order_arg_span,
102/// });
103/// ```
104///
105/// See rustc dev guide for more examples on using the `#[derive(LintDiagnostic)]`:
106/// <https://rustc-dev-guide.rust-lang.org/diagnostics/sessiondiagnostic.html>
107pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
108 LintDiagnosticDerive::new(format_ident!("diag"), s).into_tokens()
04454e1e
FG
109}
110
111/// Implements `#[derive(SessionSubdiagnostic)]`, which allows for labels, notes, helps and
112/// suggestions to be specified as a structs or enums, independent from the actual diagnostics
113/// emitting code or diagnostic derives.
114///
923072b8 115/// ```ignore (rust)
04454e1e
FG
116/// #[derive(SessionSubdiagnostic)]
117/// pub enum ExpectedIdentifierLabel<'tcx> {
064997fb 118/// #[label(parser::expected_identifier)]
04454e1e
FG
119/// WithoutFound {
120/// #[primary_span]
121/// span: Span,
122/// }
064997fb 123/// #[label(parser::expected_identifier_found)]
04454e1e
FG
124/// WithFound {
125/// #[primary_span]
126/// span: Span,
127/// found: String,
128/// }
129/// }
130///
131/// #[derive(SessionSubdiagnostic)]
064997fb 132/// #[suggestion_verbose(parser::raw_identifier)]
04454e1e
FG
133/// pub struct RawIdentifierSuggestion<'tcx> {
134/// #[primary_span]
135/// span: Span,
136/// #[applicability]
137/// applicability: Applicability,
138/// ident: Ident,
139/// }
140/// ```
141///
142/// ```fluent
f2b60f7d 143/// parser_expected_identifier = expected identifier
04454e1e 144///
f2b60f7d 145/// parser_expected_identifier-found = expected identifier, found {$found}
04454e1e 146///
f2b60f7d 147/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
04454e1e
FG
148/// ```
149///
150/// Then, later, to add the subdiagnostic:
151///
923072b8 152/// ```ignore (rust)
04454e1e
FG
153/// diag.subdiagnostic(ExpectedIdentifierLabel::WithoutFound { span });
154///
155/// diag.subdiagnostic(RawIdentifierSuggestion { span, applicability, ident });
156/// ```
157pub fn session_subdiagnostic_derive(s: Structure<'_>) -> TokenStream {
158 SessionSubdiagnosticDerive::new(s).into_tokens()
159}