@@ -37,21 +37,29 @@ const IGNORE_UI_TEST_CHECK: &[&str] = &[
3737 "E0729" , "E0789" ,
3838] ;
3939
40- pub fn check ( root_path : & Path , search_paths : & [ & Path ] , bad : & mut bool ) {
40+ macro_rules! verbose_print {
41+ ( $verbose: expr, $( $fmt: tt) * ) => {
42+ if $verbose {
43+ println!( "{}" , format_args!( $( $fmt) * ) ) ;
44+ }
45+ } ;
46+ }
47+
48+ pub fn check ( root_path : & Path , search_paths : & [ & Path ] , verbose : bool , bad : & mut bool ) {
4149 let mut errors = Vec :: new ( ) ;
4250
4351 // Stage 1: create list
44- let error_codes = extract_error_codes ( root_path, & mut errors) ;
52+ let error_codes = extract_error_codes ( root_path, & mut errors, verbose ) ;
4553 println ! ( "Found {} error codes" , error_codes. len( ) ) ;
4654
4755 // Stage 2: check list has docs
48- let no_longer_emitted = check_error_codes_docs ( root_path, & error_codes, & mut errors) ;
56+ let no_longer_emitted = check_error_codes_docs ( root_path, & error_codes, & mut errors, verbose ) ;
4957
5058 // Stage 3: check list has UI tests
51- check_error_codes_tests ( root_path, & error_codes, & mut errors) ;
59+ check_error_codes_tests ( root_path, & error_codes, & mut errors, verbose ) ;
5260
5361 // Stage 4: check list is emitted by compiler
54- check_error_codes_used ( search_paths, & error_codes, & mut errors, & no_longer_emitted) ;
62+ check_error_codes_used ( search_paths, & error_codes, & mut errors, & no_longer_emitted, verbose ) ;
5563
5664 // Print any errors.
5765 for error in errors {
@@ -60,16 +68,14 @@ pub fn check(root_path: &Path, search_paths: &[&Path], bad: &mut bool) {
6068}
6169
6270/// Stage 1: Parses a list of error codes from `error_codes.rs`.
63- fn extract_error_codes ( root_path : & Path , errors : & mut Vec < String > ) -> Vec < String > {
71+ fn extract_error_codes ( root_path : & Path , errors : & mut Vec < String > , verbose : bool ) -> Vec < String > {
6472 let path = root_path. join ( Path :: new ( ERROR_CODES_PATH ) ) ;
6573 let file =
6674 fs:: read_to_string ( & path) . unwrap_or_else ( |e| panic ! ( "failed to read `{path:?}`: {e}" ) ) ;
6775
6876 let mut error_codes = Vec :: new ( ) ;
6977 let mut reached_undocumented_codes = false ;
7078
71- let mut undocumented_count = 0 ;
72-
7379 for line in file. lines ( ) {
7480 let line = line. trim ( ) ;
7581
@@ -115,7 +121,7 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
115121 }
116122 . to_string ( ) ;
117123
118- undocumented_count += 1 ;
124+ verbose_print ! ( verbose , "warning: Error code `{}` is undocumented." , err_code ) ;
119125
120126 if error_codes. contains ( & err_code) {
121127 errors. push ( format ! ( "Found duplicate error code: `{}`" , err_code) ) ;
@@ -128,11 +134,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
128134 }
129135 }
130136
131- println ! (
132- "WARNING: {} error codes are undocumented. This *will* become a hard error." ,
133- undocumented_count
134- ) ;
135-
136137 error_codes
137138}
138139
@@ -141,13 +142,10 @@ fn check_error_codes_docs(
141142 root_path : & Path ,
142143 error_codes : & [ String ] ,
143144 errors : & mut Vec < String > ,
145+ verbose : bool ,
144146) -> Vec < String > {
145147 let docs_path = root_path. join ( Path :: new ( ERROR_DOCS_PATH ) ) ;
146148
147- let mut emit_ignore_warning = 0 ;
148- let mut emit_no_longer_warning = 0 ;
149- let mut emit_no_code_warning = 0 ;
150-
151149 let mut no_longer_emitted_codes = Vec :: new ( ) ;
152150
153151 walk ( & docs_path, & mut |_| false , & mut |entry, contents| {
@@ -179,14 +177,25 @@ fn check_error_codes_docs(
179177 // `has_test.1` checks whether the error code has a proper (definitely tested) doctest.
180178 let has_test = check_explanation_has_doctest ( & contents, & err_code) ;
181179 if has_test. 2 {
182- emit_ignore_warning += 1 ;
180+ verbose_print ! (
181+ verbose,
182+ "warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \
183+ `IGNORE_DOCTEST_CHECK` constant instead."
184+ ) ;
183185 }
184186 if has_test. 3 {
185187 no_longer_emitted_codes. push ( err_code. to_owned ( ) ) ;
186- emit_no_longer_warning += 1 ;
188+ verbose_print ! (
189+ verbose,
190+ "warning: Error code `{err_code}` is no longer emitted and should be removed entirely."
191+ ) ;
187192 }
188193 if !has_test. 0 {
189- emit_no_code_warning += 1 ;
194+ verbose_print ! (
195+ verbose,
196+ "warning: Error code `{err_code}` doesn't have a code example, all error codes are expected to have one \
197+ (even if untested)."
198+ ) ;
190199 }
191200
192201 let test_ignored = IGNORE_DOCTEST_CHECK . contains ( & err_code) ;
@@ -206,25 +215,6 @@ fn check_error_codes_docs(
206215 }
207216 } ) ;
208217
209- if emit_ignore_warning > 0 {
210- println ! (
211- "WARNING: {emit_ignore_warning} error codes use the ignore header. This should not be used, add the error codes to the \
212- `IGNORE_DOCTEST_CHECK` constant instead. This *will* become a hard error."
213- ) ;
214- }
215- if emit_no_code_warning > 0 {
216- println ! (
217- "WARNING: {emit_ignore_warning} error codes don't have a code example, all error codes are expected \
218- to have one (even if untested). This *will* become a hard error."
219- ) ;
220- }
221- if emit_no_longer_warning > 0 {
222- println ! (
223- "WARNING: {emit_no_longer_warning} error codes are no longer emitted and should be removed entirely. \
224- This *will* become a hard error."
225- ) ;
226- }
227-
228218 no_longer_emitted_codes
229219}
230220
@@ -266,18 +256,22 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo
266256}
267257
268258// Stage 3: Checks that each error code has a UI test in the correct directory
269- fn check_error_codes_tests ( root_path : & Path , error_codes : & [ String ] , errors : & mut Vec < String > ) {
259+ fn check_error_codes_tests (
260+ root_path : & Path ,
261+ error_codes : & [ String ] ,
262+ errors : & mut Vec < String > ,
263+ verbose : bool ,
264+ ) {
270265 let tests_path = root_path. join ( Path :: new ( ERROR_TESTS_PATH ) ) ;
271266
272- // Some warning counters, this whole thing is clunky but'll be removed eventually.
273- let mut no_ui_test = 0 ;
274- let mut no_error_code_in_test = 0 ;
275-
276267 for code in error_codes {
277268 let test_path = tests_path. join ( format ! ( "{}.stderr" , code) ) ;
278269
279270 if !test_path. exists ( ) && !IGNORE_UI_TEST_CHECK . contains ( & code. as_str ( ) ) {
280- no_ui_test += 1 ;
271+ verbose_print ! (
272+ verbose,
273+ "warning: Error code `{code}` needs to have at least one UI test in the `src/test/ui/error-codes/` directory`!"
274+ ) ;
281275 continue ;
282276 }
283277 if IGNORE_UI_TEST_CHECK . contains ( & code. as_str ( ) ) {
@@ -292,8 +286,9 @@ fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mu
292286 let file = match fs:: read_to_string ( & test_path) {
293287 Ok ( file) => file,
294288 Err ( err) => {
295- println ! (
296- "WARNING: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n {err}" ,
289+ verbose_print ! (
290+ verbose,
291+ "warning: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n {err}" ,
297292 test_path. display( )
298293 ) ;
299294 continue ;
@@ -314,22 +309,12 @@ fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mu
314309 }
315310
316311 if !found_code {
317- no_error_code_in_test += 1 ;
312+ verbose_print ! (
313+ verbose,
314+ "warning: Error code {code}`` has a UI test file, but doesn't contain its own error code!"
315+ ) ;
318316 }
319317 }
320-
321- if no_error_code_in_test > 0 {
322- println ! (
323- "WARNING: {no_error_code_in_test} error codes have a UI test file, but don't contain their own error code!"
324- ) ;
325- }
326-
327- if no_ui_test > 0 {
328- println ! (
329- "WARNING: {no_ui_test} error codes need to have at least one UI test in the `src/test/ui/error-codes/` directory`! \
330- This *will* become a hard error."
331- ) ;
332- }
333318}
334319
335320/// Stage 4: Search `compiler/` and ensure that every error code is actually used by the compiler and that no undocumented error codes exist.
@@ -338,6 +323,7 @@ fn check_error_codes_used(
338323 error_codes : & [ String ] ,
339324 errors : & mut Vec < String > ,
340325 no_longer_emitted : & [ String ] ,
326+ verbose : bool ,
341327) {
342328 // We want error codes which match the following cases:
343329 //
@@ -380,21 +366,16 @@ fn check_error_codes_used(
380366 }
381367 } ) ;
382368
383- let mut used_when_shouldnt = 0 ;
384-
385369 for code in error_codes {
386370 if !found_codes. contains ( code) && !no_longer_emitted. contains ( code) {
387371 errors. push ( format ! ( "Error code `{code}` exists, but is not emitted by the compiler!" ) )
388372 }
389373
390374 if found_codes. contains ( code) && no_longer_emitted. contains ( code) {
391- used_when_shouldnt += 1 ;
375+ verbose_print ! (
376+ verbose,
377+ "warning: Error code `{code}` is used when it's marked as \" no longer emitted\" "
378+ ) ;
392379 }
393380 }
394-
395- if used_when_shouldnt > 0 {
396- println ! (
397- "WARNING: {used_when_shouldnt} error codes are used when they are marked as \" no longer emitted\" "
398- ) ;
399- }
400381}
0 commit comments