]>
Commit | Line | Data |
---|---|---|
04454e1e | 1 | mod diagnostic; |
064997fb | 2 | mod diagnostic_builder; |
04454e1e | 3 | mod error; |
923072b8 | 4 | mod fluent; |
04454e1e FG |
5 | mod subdiagnostic; |
6 | mod utils; | |
7 | ||
064997fb | 8 | use diagnostic::{LintDiagnosticDerive, SessionDiagnosticDerive}; |
923072b8 | 9 | pub(crate) use fluent::fluent_messages; |
04454e1e FG |
10 | use proc_macro2::TokenStream; |
11 | use quote::format_ident; | |
12 | use subdiagnostic::SessionSubdiagnosticDerive; | |
13 | use 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 | 61 | pub 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> | |
107 | pub 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 | /// ``` | |
157 | pub fn session_subdiagnostic_derive(s: Structure<'_>) -> TokenStream { | |
158 | SessionSubdiagnosticDerive::new(s).into_tokens() | |
159 | } |