3
3
4
4
use std:: collections:: HashMap ;
5
5
use std:: ffi:: OsStr ;
6
+ use std:: fs:: read_to_string;
7
+ use std:: io:: Read ;
6
8
use std:: path:: Path ;
7
9
8
10
// A few of those error codes can't be tested but all the others can and *should* be tested!
@@ -50,41 +52,69 @@ const WHITELIST: &[&str] = &[
50
52
"E0729" ,
51
53
] ;
52
54
53
- fn extract_error_codes ( f : & str , error_codes : & mut HashMap < String , bool > ) {
55
+ fn check_error_code_explanation (
56
+ f : & str ,
57
+ error_codes : & mut HashMap < String , bool > ,
58
+ err_code : String ,
59
+ ) {
60
+ for line in f. lines ( ) {
61
+ let s = line. trim ( ) ;
62
+ if s. starts_with ( "```" ) && s. contains ( "compile_fail" ) && s. contains ( 'E' ) {
63
+ error_codes. insert ( err_code, true ) ;
64
+ return ;
65
+ } else if s. starts_with ( "#### Note: this error code is no longer emitted by the compiler" ) {
66
+ error_codes. get_mut ( & err_code) . map ( |x| * x = true ) ;
67
+ return ;
68
+ }
69
+ }
70
+ }
71
+
72
+ macro_rules! some_or_continue {
73
+ ( $e: expr) => (
74
+ match $e {
75
+ Some ( e) => e,
76
+ None => continue ,
77
+ }
78
+ ) ;
79
+ }
80
+
81
+ fn extract_error_codes ( f : & str , error_codes : & mut HashMap < String , bool > , path : & Path ) {
54
82
let mut reached_no_explanation = false ;
55
- let mut last_error_code = None ;
56
83
57
84
for line in f. lines ( ) {
58
85
let s = line. trim ( ) ;
59
- if s. starts_with ( 'E' ) && s. ends_with ( ": r## \" ") {
86
+ if !reached_no_explanation && s. starts_with ( 'E' ) && s. contains ( "include_str!( \" ") {
60
87
if let Some ( err_code) = s. splitn ( 2 , ':' ) . next ( ) {
61
88
let err_code = err_code. to_owned ( ) ;
62
- last_error_code = Some ( err_code. clone ( ) ) ;
63
89
if !error_codes. contains_key ( & err_code) {
64
- error_codes. insert ( err_code, false ) ;
90
+ error_codes. insert ( err_code. clone ( ) , false ) ;
65
91
}
66
- }
67
- } else if s. starts_with ( "```" ) && s. contains ( "compile_fail" ) && s. contains ( 'E' ) {
68
- if let Some ( err_code) = s. splitn ( 2 , 'E' ) . skip ( 1 ) . next ( ) {
69
- if let Some ( err_code) = err_code. splitn ( 2 , ',' ) . next ( ) {
70
- let nb = error_codes. entry ( format ! ( "E{}" , err_code) ) . or_insert ( false ) ;
71
- * nb = true ;
92
+ // Now we extract the tests from the markdown file!
93
+ let md = some_or_continue ! ( s. splitn( 2 , "include_str!(\" " ) . skip( 1 ) . next( ) ) ;
94
+ let md_file_name = some_or_continue ! ( md. splitn( 2 , "\" )" ) . next( ) ) ;
95
+ let path = some_or_continue ! ( path. parent( ) ) . join ( md_file_name) ;
96
+ match read_to_string ( & path) {
97
+ Ok ( content) => {
98
+ check_error_code_explanation (
99
+ & content,
100
+ error_codes,
101
+ err_code,
102
+ ) ;
103
+ }
104
+ Err ( e) => {
105
+ eprintln ! ( "Couldn't read `{}`: {}" , path. display( ) , e) ;
106
+ }
72
107
}
73
108
}
74
- } else if s == ";" {
75
- reached_no_explanation = true ;
76
109
} else if reached_no_explanation && s. starts_with ( 'E' ) {
77
110
if let Some ( err_code) = s. splitn ( 2 , ',' ) . next ( ) {
78
111
let err_code = err_code. to_owned ( ) ;
79
112
if !error_codes. contains_key ( & err_code) { // this check should *never* fail!
80
113
error_codes. insert ( err_code, false ) ;
81
114
}
82
115
}
83
- } else if s. starts_with ( "#### Note: this error code is no longer emitted by the compiler" ) {
84
- if let Some ( last) = last_error_code {
85
- error_codes. get_mut ( & last) . map ( |x| * x = true ) ;
86
- }
87
- last_error_code = None ;
116
+ } else if s == ";" {
117
+ reached_no_explanation = true ;
88
118
}
89
119
}
90
120
}
@@ -111,7 +141,7 @@ pub fn check(path: &Path, bad: &mut bool) {
111
141
& mut |entry, contents| {
112
142
let file_name = entry. file_name ( ) ;
113
143
if file_name == "error_codes.rs" {
114
- extract_error_codes ( contents, & mut error_codes) ;
144
+ extract_error_codes ( contents, & mut error_codes, entry . path ( ) ) ;
115
145
} else if entry. path ( ) . extension ( ) == Some ( OsStr :: new ( "stderr" ) ) {
116
146
extract_error_codes_from_tests ( contents, & mut error_codes) ;
117
147
}
0 commit comments