2
2
3
3
use crate :: diagnostics:: diagnostic_builder:: { DiagnosticDeriveBuilder , DiagnosticDeriveKind } ;
4
4
use crate :: diagnostics:: error:: { span_err, DiagnosticDeriveError } ;
5
- use crate :: diagnostics:: utils:: { build_field_mapping , SetOnce } ;
5
+ use crate :: diagnostics:: utils:: SetOnce ;
6
6
use proc_macro2:: TokenStream ;
7
7
use quote:: quote;
8
- use syn:: spanned:: Spanned ;
9
8
use synstructure:: Structure ;
10
9
11
10
/// The central struct for constructing the `into_diagnostic` method from an annotated struct.
@@ -18,13 +17,7 @@ pub(crate) struct DiagnosticDerive<'a> {
18
17
impl < ' a > DiagnosticDerive < ' a > {
19
18
pub ( crate ) fn new ( diag : syn:: Ident , handler : syn:: Ident , structure : Structure < ' a > ) -> Self {
20
19
Self {
21
- builder : DiagnosticDeriveBuilder {
22
- diag,
23
- fields : build_field_mapping ( & structure) ,
24
- kind : DiagnosticDeriveKind :: Diagnostic ,
25
- code : None ,
26
- slug : None ,
27
- } ,
20
+ builder : DiagnosticDeriveBuilder { diag, kind : DiagnosticDeriveKind :: Diagnostic } ,
28
21
handler,
29
22
structure,
30
23
}
@@ -33,52 +26,35 @@ impl<'a> DiagnosticDerive<'a> {
33
26
pub ( crate ) fn into_tokens ( self ) -> TokenStream {
34
27
let DiagnosticDerive { mut structure, handler, mut builder } = self ;
35
28
36
- let ast = structure. ast ( ) ;
37
- let implementation = {
38
- if let syn:: Data :: Struct ( ..) = ast. data {
39
- let preamble = builder. preamble ( & structure) ;
40
- let ( attrs, args) = builder. body ( & mut structure) ;
41
-
42
- let span = ast. span ( ) . unwrap ( ) ;
43
- let diag = & builder. diag ;
44
- let init = match builder. slug . value ( ) {
45
- None => {
46
- span_err ( span, "diagnostic slug not specified" )
47
- . help ( & format ! (
48
- "specify the slug as the first argument to the `#[diag(...)]` attribute, \
49
- such as `#[diag(typeck::example_error)]`",
50
- ) )
51
- . emit ( ) ;
52
- return DiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
53
- }
54
- Some ( slug) => {
55
- quote ! {
56
- let mut #diag = #handler. struct_diagnostic( rustc_errors:: fluent:: #slug) ;
57
- }
58
- }
59
- } ;
60
-
61
- quote ! {
62
- #init
63
- #preamble
64
- match self {
65
- #attrs
66
- }
67
- match self {
68
- #args
29
+ let implementation = builder. each_variant ( & mut structure, |mut builder, variant| {
30
+ let preamble = builder. preamble ( & variant) ;
31
+ let body = builder. body ( & variant) ;
32
+
33
+ let diag = & builder. parent . diag ;
34
+ let init = match builder. slug . value_ref ( ) {
35
+ None => {
36
+ span_err ( builder. span , "diagnostic slug not specified" )
37
+ . help ( & format ! (
38
+ "specify the slug as the first argument to the `#[diag(...)]` \
39
+ attribute, such as `#[diag(typeck::example_error)]`",
40
+ ) )
41
+ . emit ( ) ;
42
+ return DiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
43
+ }
44
+ Some ( slug) => {
45
+ quote ! {
46
+ let mut #diag = #handler. struct_diagnostic( rustc_errors:: fluent:: #slug) ;
69
47
}
70
- #diag
71
48
}
72
- } else {
73
- span_err (
74
- ast. span ( ) . unwrap ( ) ,
75
- "`#[derive(Diagnostic)]` can only be used on structs" ,
76
- )
77
- . emit ( ) ;
49
+ } ;
78
50
79
- DiagnosticDeriveError :: ErrorHandled . to_compile_error ( )
51
+ quote ! {
52
+ #init
53
+ #preamble
54
+ #body
55
+ #diag
80
56
}
81
- } ;
57
+ } ) ;
82
58
83
59
structure. gen_impl ( quote ! {
84
60
gen impl <' __diagnostic_handler_sess, G >
@@ -107,68 +83,43 @@ pub(crate) struct LintDiagnosticDerive<'a> {
107
83
impl < ' a > LintDiagnosticDerive < ' a > {
108
84
pub ( crate ) fn new ( diag : syn:: Ident , structure : Structure < ' a > ) -> Self {
109
85
Self {
110
- builder : DiagnosticDeriveBuilder {
111
- diag,
112
- fields : build_field_mapping ( & structure) ,
113
- kind : DiagnosticDeriveKind :: LintDiagnostic ,
114
- code : None ,
115
- slug : None ,
116
- } ,
86
+ builder : DiagnosticDeriveBuilder { diag, kind : DiagnosticDeriveKind :: LintDiagnostic } ,
117
87
structure,
118
88
}
119
89
}
120
90
121
91
pub ( crate ) fn into_tokens ( self ) -> TokenStream {
122
92
let LintDiagnosticDerive { mut structure, mut builder } = self ;
123
93
124
- let ast = structure. ast ( ) ;
125
- let implementation = {
126
- if let syn:: Data :: Struct ( ..) = ast. data {
127
- let preamble = builder. preamble ( & structure) ;
128
- let ( attrs, args) = builder. body ( & mut structure) ;
129
-
130
- let diag = & builder. diag ;
131
- let span = ast. span ( ) . unwrap ( ) ;
132
- let init = match builder. slug . value ( ) {
133
- None => {
134
- span_err ( span, "diagnostic slug not specified" )
135
- . help ( & format ! (
136
- "specify the slug as the first argument to the attribute, such as \
137
- `#[diag(typeck::example_error)]`",
138
- ) )
139
- . emit ( ) ;
140
- return DiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
141
- }
142
- Some ( slug) => {
143
- quote ! {
144
- let mut #diag = #diag. build( rustc_errors:: fluent:: #slug) ;
145
- }
146
- }
147
- } ;
148
-
149
- let implementation = quote ! {
150
- #init
151
- #preamble
152
- match self {
153
- #attrs
154
- }
155
- match self {
156
- #args
94
+ let implementation = builder. each_variant ( & mut structure, |mut builder, variant| {
95
+ let preamble = builder. preamble ( & variant) ;
96
+ let body = builder. body ( & variant) ;
97
+
98
+ let diag = & builder. parent . diag ;
99
+ let init = match builder. slug . value_ref ( ) {
100
+ None => {
101
+ span_err ( builder. span , "diagnostic slug not specified" )
102
+ . help ( & format ! (
103
+ "specify the slug as the first argument to the attribute, such as \
104
+ `#[diag(typeck::example_error)]`",
105
+ ) )
106
+ . emit ( ) ;
107
+ return DiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
108
+ }
109
+ Some ( slug) => {
110
+ quote ! {
111
+ let mut #diag = #diag. build( rustc_errors:: fluent:: #slug) ;
157
112
}
158
- #diag. emit( ) ;
159
- } ;
160
-
161
- implementation
162
- } else {
163
- span_err (
164
- ast. span ( ) . unwrap ( ) ,
165
- "`#[derive(LintDiagnostic)]` can only be used on structs" ,
166
- )
167
- . emit ( ) ;
113
+ }
114
+ } ;
168
115
169
- DiagnosticDeriveError :: ErrorHandled . to_compile_error ( )
116
+ quote ! {
117
+ #init
118
+ #preamble
119
+ #body
120
+ #diag. emit( ) ;
170
121
}
171
- } ;
122
+ } ) ;
172
123
173
124
let diag = & builder. diag ;
174
125
structure. gen_impl ( quote ! {
0 commit comments