@@ -21,7 +21,7 @@ use std::io::prelude::*;
21
21
use std:: io;
22
22
use std:: rc:: Rc ;
23
23
use term;
24
- use std:: collections:: HashMap ;
24
+ use std:: collections:: { HashMap , HashSet } ;
25
25
use std:: cmp:: min;
26
26
use unicode_width;
27
27
@@ -107,6 +107,7 @@ pub struct EmitterWriter {
107
107
cm : Option < Rc < CodeMapper > > ,
108
108
short_message : bool ,
109
109
teach : bool ,
110
+ error_codes : HashSet < String > ,
110
111
}
111
112
112
113
struct FileWithAnnotatedLines {
@@ -115,6 +116,30 @@ struct FileWithAnnotatedLines {
115
116
multiline_depth : usize ,
116
117
}
117
118
119
+ impl Drop for EmitterWriter {
120
+ fn drop ( & mut self ) {
121
+ if !self . short_message && !self . error_codes . is_empty ( ) {
122
+ let mut error_codes = self . error_codes . clone ( ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ;
123
+ error_codes. sort ( ) ;
124
+ if error_codes. len ( ) > 1 {
125
+ writeln ! ( self . dst,
126
+ "You've got a few errors: {}" ,
127
+ error_codes. join( ", " ) ) . expect ( "failed to give tips..." ) ;
128
+ writeln ! ( self . dst,
129
+ "If you want more information on an error, try using \
130
+ \" rustc --explain {}\" ",
131
+ & error_codes[ 0 ] ) . expect ( "failed to give tips..." ) ;
132
+ } else {
133
+ writeln ! ( self . dst,
134
+ "If you want more information on this error, try using \
135
+ \" rustc --explain {}\" ",
136
+ & error_codes[ 0 ] ) . expect ( "failed to give tips..." ) ;
137
+ }
138
+ self . dst . flush ( ) . expect ( "failed to emit errors" ) ;
139
+ }
140
+ }
141
+ }
142
+
118
143
impl EmitterWriter {
119
144
pub fn stderr ( color_config : ColorConfig ,
120
145
code_map : Option < Rc < CodeMapper > > ,
@@ -128,13 +153,15 @@ impl EmitterWriter {
128
153
cm : code_map,
129
154
short_message,
130
155
teach,
156
+ error_codes : HashSet :: new ( ) ,
131
157
}
132
158
} else {
133
159
EmitterWriter {
134
160
dst : Raw ( Box :: new ( io:: stderr ( ) ) ) ,
135
161
cm : code_map,
136
162
short_message,
137
163
teach,
164
+ error_codes : HashSet :: new ( ) ,
138
165
}
139
166
}
140
167
}
@@ -149,6 +176,7 @@ impl EmitterWriter {
149
176
cm : code_map,
150
177
short_message,
151
178
teach,
179
+ error_codes : HashSet :: new ( ) ,
152
180
}
153
181
}
154
182
@@ -975,12 +1003,14 @@ impl EmitterWriter {
975
1003
if primary_span != & & DUMMY_SP {
976
1004
( cm. lookup_char_pos ( primary_span. lo ( ) ) , cm)
977
1005
} else {
978
- emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ) ?;
1006
+ emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ,
1007
+ & mut self . error_codes ) ?;
979
1008
return Ok ( ( ) ) ;
980
1009
}
981
1010
} else {
982
1011
// If we don't have span information, emit and exit
983
- emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ) ?;
1012
+ emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ,
1013
+ & mut self . error_codes ) ?;
984
1014
return Ok ( ( ) ) ;
985
1015
} ;
986
1016
if let Ok ( pos) =
@@ -1153,7 +1183,8 @@ impl EmitterWriter {
1153
1183
}
1154
1184
1155
1185
// final step: take our styled buffer, render it, then output it
1156
- emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ) ?;
1186
+ emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ,
1187
+ & mut self . error_codes ) ?;
1157
1188
1158
1189
Ok ( ( ) )
1159
1190
@@ -1241,7 +1272,8 @@ impl EmitterWriter {
1241
1272
let msg = format ! ( "and {} other candidates" , suggestions. len( ) - MAX_SUGGESTIONS ) ;
1242
1273
buffer. puts ( row_num, 0 , & msg, Style :: NoStyle ) ;
1243
1274
}
1244
- emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ) ?;
1275
+ emit_to_destination ( & buffer. render ( ) , level, & mut self . dst , self . short_message ,
1276
+ & mut self . error_codes ) ?;
1245
1277
}
1246
1278
Ok ( ( ) )
1247
1279
}
@@ -1269,7 +1301,7 @@ impl EmitterWriter {
1269
1301
draw_col_separator_no_space ( & mut buffer, 0 , max_line_num_len + 1 ) ;
1270
1302
}
1271
1303
match emit_to_destination ( & buffer. render ( ) , level, & mut self . dst ,
1272
- self . short_message ) {
1304
+ self . short_message , & mut self . error_codes ) {
1273
1305
Ok ( ( ) ) => ( ) ,
1274
1306
Err ( e) => panic ! ( "failed to emit error: {}" , e)
1275
1307
}
@@ -1362,7 +1394,8 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
1362
1394
fn emit_to_destination ( rendered_buffer : & Vec < Vec < StyledString > > ,
1363
1395
lvl : & Level ,
1364
1396
dst : & mut Destination ,
1365
- short_message : bool )
1397
+ short_message : bool ,
1398
+ error_codes : & mut HashSet < String > )
1366
1399
-> io:: Result < ( ) > {
1367
1400
use lock;
1368
1401
@@ -1383,6 +1416,9 @@ fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
1383
1416
for part in line {
1384
1417
dst. apply_style ( lvl. clone ( ) , part. style ) ?;
1385
1418
write ! ( dst, "{}" , part. text) ?;
1419
+ if !short_message && part. text . len ( ) == 12 && part. text . starts_with ( "error[E" ) {
1420
+ error_codes. insert ( part. text [ 6 ..11 ] . to_owned ( ) ) ;
1421
+ }
1386
1422
dst. reset_attrs ( ) ?;
1387
1423
}
1388
1424
if !short_message {
0 commit comments