10
10
11
11
use CodeSuggestion ;
12
12
use Level ;
13
- use RenderSpan ;
14
- use RenderSpan :: { Suggestion , Guesses } ;
15
13
use std:: { fmt, iter} ;
16
14
use syntax_pos:: { MultiSpan , Span } ;
17
15
use snippet:: Style ;
@@ -24,6 +22,19 @@ pub struct Diagnostic {
24
22
pub code : Option < String > ,
25
23
pub span : MultiSpan ,
26
24
pub children : Vec < SubDiagnostic > ,
25
+ pub code_hints : Option < DiagnosticCodeHint > ,
26
+ }
27
+
28
+ #[ derive( Clone , Debug , PartialEq ) ]
29
+ pub enum DiagnosticCodeHint {
30
+ Suggestion {
31
+ msg : String ,
32
+ sugg : CodeSuggestion ,
33
+ } ,
34
+ Guesses {
35
+ msg : String ,
36
+ guesses : Vec < CodeSuggestion > ,
37
+ } ,
27
38
}
28
39
29
40
/// For example a note attached to an error.
@@ -32,7 +43,7 @@ pub struct SubDiagnostic {
32
43
pub level : Level ,
33
44
pub message : Vec < ( String , Style ) > ,
34
45
pub span : MultiSpan ,
35
- pub render_span : Option < RenderSpan > ,
46
+ pub render_span : Option < MultiSpan > ,
36
47
}
37
48
38
49
impl Diagnostic {
@@ -47,6 +58,7 @@ impl Diagnostic {
47
58
code : code,
48
59
span : MultiSpan :: new ( ) ,
49
60
children : vec ! [ ] ,
61
+ code_hints : None ,
50
62
}
51
63
}
52
64
@@ -109,60 +121,62 @@ impl Diagnostic {
109
121
}
110
122
111
123
pub fn note ( & mut self , msg : & str ) -> & mut Self {
112
- self . sub ( Level :: Note , msg, MultiSpan :: new ( ) , None ) ;
124
+ self . sub ( Level :: Note , msg, MultiSpan :: new ( ) ) ;
113
125
self
114
126
}
115
127
116
128
pub fn highlighted_note ( & mut self , msg : Vec < ( String , Style ) > ) -> & mut Self {
117
- self . sub_with_highlights ( Level :: Note , msg, MultiSpan :: new ( ) , None ) ;
129
+ self . sub_with_highlights ( Level :: Note , msg, MultiSpan :: new ( ) ) ;
118
130
self
119
131
}
120
132
121
133
pub fn span_note < S : Into < MultiSpan > > ( & mut self ,
122
134
sp : S ,
123
135
msg : & str )
124
136
-> & mut Self {
125
- self . sub ( Level :: Note , msg, sp. into ( ) , None ) ;
137
+ self . sub ( Level :: Note , msg, sp. into ( ) ) ;
126
138
self
127
139
}
128
140
129
141
pub fn warn ( & mut self , msg : & str ) -> & mut Self {
130
- self . sub ( Level :: Warning , msg, MultiSpan :: new ( ) , None ) ;
142
+ self . sub ( Level :: Warning , msg, MultiSpan :: new ( ) ) ;
131
143
self
132
144
}
133
145
134
146
pub fn span_warn < S : Into < MultiSpan > > ( & mut self ,
135
147
sp : S ,
136
148
msg : & str )
137
149
-> & mut Self {
138
- self . sub ( Level :: Warning , msg, sp. into ( ) , None ) ;
150
+ self . sub ( Level :: Warning , msg, sp. into ( ) ) ;
139
151
self
140
152
}
141
153
142
154
pub fn help ( & mut self , msg : & str ) -> & mut Self {
143
- self . sub ( Level :: Help , msg, MultiSpan :: new ( ) , None ) ;
155
+ self . sub ( Level :: Help , msg, MultiSpan :: new ( ) ) ;
144
156
self
145
157
}
146
158
147
159
pub fn span_help < S : Into < MultiSpan > > ( & mut self ,
148
160
sp : S ,
149
161
msg : & str )
150
162
-> & mut Self {
151
- self . sub ( Level :: Help , msg, sp. into ( ) , None ) ;
163
+ self . sub ( Level :: Help , msg, sp. into ( ) ) ;
152
164
self
153
165
}
154
166
155
167
/// Prints out a message with a suggested edit of the code.
156
168
///
157
169
/// See `diagnostic::RenderSpan::Suggestion` for more information.
158
170
pub fn span_suggestion ( & mut self , sp : Span , msg : & str , suggestion : String ) -> & mut Self {
159
- self . sub ( Level :: Help ,
160
- msg,
161
- MultiSpan :: new ( ) ,
162
- Some ( Suggestion ( CodeSuggestion {
163
- msp : sp. into ( ) ,
164
- substitutes : vec ! [ suggestion] ,
165
- } ) ) ) ;
171
+ assert ! ( self . code_hints. is_none( ) ,
172
+ "use guesses to assign multiple suggestions to an error" ) ;
173
+ self . code_hints = Some ( DiagnosticCodeHint :: Suggestion {
174
+ sugg : CodeSuggestion {
175
+ msp : sp. into ( ) ,
176
+ substitutes : vec ! [ suggestion] ,
177
+ } ,
178
+ msg : msg. to_owned ( ) ,
179
+ } ) ;
166
180
self
167
181
}
168
182
@@ -174,13 +188,16 @@ impl Diagnostic {
174
188
pub fn guesses < I > ( & mut self , sp : Span , msg : & str , guesses : I ) -> & mut Self
175
189
where I : IntoIterator < Item = String >
176
190
{
177
- self . sub ( Level :: Help ,
178
- msg,
179
- MultiSpan :: new ( ) ,
180
- Some ( Guesses ( guesses. into_iter ( ) . map ( |guess| CodeSuggestion {
181
- msp : sp. into ( ) ,
182
- substitutes : vec ! [ guess] ,
183
- } ) . collect ( ) ) ) ) ;
191
+ assert ! ( self . code_hints. is_none( ) ,
192
+ "cannot attach multiple guesses to the same error" ) ;
193
+ let guesses = guesses. into_iter ( ) . map ( |guess| CodeSuggestion {
194
+ msp : sp. into ( ) ,
195
+ substitutes : vec ! [ guess] ,
196
+ } ) . collect ( ) ;
197
+ self . code_hints = Some ( DiagnosticCodeHint :: Guesses {
198
+ guesses : guesses,
199
+ msg : msg. to_owned ( ) ,
200
+ } ) ;
184
201
self
185
202
}
186
203
@@ -223,29 +240,25 @@ impl Diagnostic {
223
240
fn sub ( & mut self ,
224
241
level : Level ,
225
242
message : & str ,
226
- span : MultiSpan ,
227
- render_span : Option < RenderSpan > ) {
228
- let sub = SubDiagnostic {
229
- level : level,
230
- message : vec ! [ ( message. to_owned( ) , Style :: NoStyle ) ] ,
231
- span : span,
232
- render_span : render_span,
233
- } ;
234
- self . children . push ( sub) ;
243
+ span : MultiSpan ) {
244
+ self . sub_with_highlights (
245
+ level,
246
+ vec ! [ ( message. to_owned( ) , Style :: NoStyle ) ] ,
247
+ span,
248
+ ) ;
235
249
}
236
250
237
251
/// Convenience function for internal use, clients should use one of the
238
252
/// public methods above.
239
253
fn sub_with_highlights ( & mut self ,
240
254
level : Level ,
241
255
message : Vec < ( String , Style ) > ,
242
- span : MultiSpan ,
243
- render_span : Option < RenderSpan > ) {
256
+ span : MultiSpan ) {
244
257
let sub = SubDiagnostic {
245
258
level : level,
246
259
message : message,
247
260
span : span,
248
- render_span : render_span ,
261
+ render_span : None ,
249
262
} ;
250
263
self . children . push ( sub) ;
251
264
}
0 commit comments