1010
1111use CodeSuggestion ;
1212use Level ;
13- use RenderSpan ;
14- use RenderSpan :: { Suggestion , Guesses } ;
1513use std:: { fmt, iter} ;
1614use syntax_pos:: { MultiSpan , Span } ;
1715use snippet:: Style ;
@@ -24,6 +22,19 @@ pub struct Diagnostic {
2422 pub code : Option < String > ,
2523 pub span : MultiSpan ,
2624 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+ } ,
2738}
2839
2940/// For example a note attached to an error.
@@ -32,7 +43,7 @@ pub struct SubDiagnostic {
3243 pub level : Level ,
3344 pub message : Vec < ( String , Style ) > ,
3445 pub span : MultiSpan ,
35- pub render_span : Option < RenderSpan > ,
46+ pub render_span : Option < MultiSpan > ,
3647}
3748
3849impl Diagnostic {
@@ -47,6 +58,7 @@ impl Diagnostic {
4758 code : code,
4859 span : MultiSpan :: new ( ) ,
4960 children : vec ! [ ] ,
61+ code_hints : None ,
5062 }
5163 }
5264
@@ -109,60 +121,62 @@ impl Diagnostic {
109121 }
110122
111123 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 ( ) ) ;
113125 self
114126 }
115127
116128 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 ( ) ) ;
118130 self
119131 }
120132
121133 pub fn span_note < S : Into < MultiSpan > > ( & mut self ,
122134 sp : S ,
123135 msg : & str )
124136 -> & mut Self {
125- self . sub ( Level :: Note , msg, sp. into ( ) , None ) ;
137+ self . sub ( Level :: Note , msg, sp. into ( ) ) ;
126138 self
127139 }
128140
129141 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 ( ) ) ;
131143 self
132144 }
133145
134146 pub fn span_warn < S : Into < MultiSpan > > ( & mut self ,
135147 sp : S ,
136148 msg : & str )
137149 -> & mut Self {
138- self . sub ( Level :: Warning , msg, sp. into ( ) , None ) ;
150+ self . sub ( Level :: Warning , msg, sp. into ( ) ) ;
139151 self
140152 }
141153
142154 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 ( ) ) ;
144156 self
145157 }
146158
147159 pub fn span_help < S : Into < MultiSpan > > ( & mut self ,
148160 sp : S ,
149161 msg : & str )
150162 -> & mut Self {
151- self . sub ( Level :: Help , msg, sp. into ( ) , None ) ;
163+ self . sub ( Level :: Help , msg, sp. into ( ) ) ;
152164 self
153165 }
154166
155167 /// Prints out a message with a suggested edit of the code.
156168 ///
157169 /// See `diagnostic::RenderSpan::Suggestion` for more information.
158170 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+ } ) ;
166180 self
167181 }
168182
@@ -174,13 +188,16 @@ impl Diagnostic {
174188 pub fn guesses < I > ( & mut self , sp : Span , msg : & str , guesses : I ) -> & mut Self
175189 where I : IntoIterator < Item = String >
176190 {
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+ } ) ;
184201 self
185202 }
186203
@@ -223,29 +240,25 @@ impl Diagnostic {
223240 fn sub ( & mut self ,
224241 level : Level ,
225242 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+ ) ;
235249 }
236250
237251 /// Convenience function for internal use, clients should use one of the
238252 /// public methods above.
239253 fn sub_with_highlights ( & mut self ,
240254 level : Level ,
241255 message : Vec < ( String , Style ) > ,
242- span : MultiSpan ,
243- render_span : Option < RenderSpan > ) {
256+ span : MultiSpan ) {
244257 let sub = SubDiagnostic {
245258 level : level,
246259 message : message,
247260 span : span,
248- render_span : render_span ,
261+ render_span : None ,
249262 } ;
250263 self . children . push ( sub) ;
251264 }
0 commit comments