11//! Checks that all error codes have at least one test to prevent having error
22//! codes that are silently not thrown by the compiler anymore.
33
4- use std:: collections:: HashMap ;
4+ use std:: collections:: { HashMap , HashSet } ;
55use std:: ffi:: OsStr ;
66use std:: fs:: read_to_string;
77use std:: path:: Path ;
@@ -205,6 +205,7 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
205205 let mut found_explanations = 0 ;
206206 let mut found_tests = 0 ;
207207 let mut error_codes: HashMap < String , ErrorCodeStatus > = HashMap :: new ( ) ;
208+ let mut explanations: HashSet < String > = HashSet :: new ( ) ;
208209 // We want error codes which match the following cases:
209210 //
210211 // * foo(a, E0111, a)
@@ -218,17 +219,27 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
218219 for path in paths {
219220 super :: walk ( path, & mut |path| super :: filter_dirs ( path) , & mut |entry, contents| {
220221 let file_name = entry. file_name ( ) ;
222+ let entry_path = entry. path ( ) ;
223+
221224 if file_name == "error_codes.rs" {
222225 extract_error_codes ( contents, & mut error_codes, entry. path ( ) , & mut errors) ;
223226 found_explanations += 1 ;
224- } else if entry . path ( ) . extension ( ) == Some ( OsStr :: new ( "stderr" ) ) {
227+ } else if entry_path . extension ( ) == Some ( OsStr :: new ( "stderr" ) ) {
225228 extract_error_codes_from_tests ( contents, & mut error_codes) ;
226229 found_tests += 1 ;
227- } else if entry . path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) {
230+ } else if entry_path . extension ( ) == Some ( OsStr :: new ( "rs" ) ) {
228231 let path = entry. path ( ) . to_string_lossy ( ) ;
229232 if PATHS_TO_IGNORE_FOR_EXTRACTION . iter ( ) . all ( |c| !path. contains ( c) ) {
230233 extract_error_codes_from_source ( contents, & mut error_codes, & regex) ;
231234 }
235+ } else if entry_path
236+ . parent ( )
237+ . and_then ( |p| p. file_name ( ) )
238+ . map ( |p| p == "error_codes" )
239+ . unwrap_or ( false )
240+ && entry_path. extension ( ) == Some ( OsStr :: new ( "md" ) )
241+ {
242+ explanations. insert ( file_name. to_str ( ) . unwrap ( ) . replace ( ".md" , "" ) ) ;
232243 }
233244 } ) ;
234245 }
@@ -240,6 +251,10 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
240251 eprintln ! ( "No error code was found in compilation errors!" ) ;
241252 * bad = true ;
242253 }
254+ if explanations. is_empty ( ) {
255+ eprintln ! ( "No error code explanation was found!" ) ;
256+ * bad = true ;
257+ }
243258 if errors. is_empty ( ) {
244259 println ! ( "Found {} error codes" , error_codes. len( ) ) ;
245260
@@ -282,11 +297,21 @@ pub fn check(paths: &[&Path], bad: &mut bool) {
282297 }
283298 }
284299 }
300+ if errors. is_empty ( ) {
301+ for explanation in explanations {
302+ if !error_codes. contains_key ( & explanation) {
303+ errors. push ( format ! (
304+ "{} error code explanation should be listed in `error_codes.rs`" ,
305+ explanation
306+ ) ) ;
307+ }
308+ }
309+ }
285310 errors. sort ( ) ;
286311 for err in & errors {
287312 eprintln ! ( "{}" , err) ;
288313 }
289- println ! ( "Found {} error codes with no tests " , errors. len( ) ) ;
314+ println ! ( "Found {} error(s) in error codes " , errors. len( ) ) ;
290315 if !errors. is_empty ( ) {
291316 * bad = true ;
292317 }
0 commit comments