1717//! `// ignore-tidy-CHECK-NAME`. 
1818
1919use  crate :: walk:: { filter_dirs,  walk} ; 
20- use  regex:: Regex ; 
20+ use  regex:: { Regex ,   RegexSet } ; 
2121use  std:: path:: Path ; 
2222
2323/// Error code markdown is restricted to 80 columns because they can be 
@@ -225,6 +225,7 @@ pub fn check(path: &Path, bad: &mut bool) {
225225        . chain ( PROBLEMATIC_CONSTS . iter ( ) . map ( |v| format ! ( "{:x}" ,  v) ) ) 
226226        . chain ( PROBLEMATIC_CONSTS . iter ( ) . map ( |v| format ! ( "{:X}" ,  v) ) ) 
227227        . collect ( ) ; 
228+     let  problematic_regex = RegexSet :: new ( problematic_consts_strings. as_slice ( ) ) . unwrap ( ) ; 
228229    walk ( path,  & mut  skip,  & mut  |entry,  contents| { 
229230        let  file = entry. path ( ) ; 
230231        let  filename = file. file_name ( ) . unwrap ( ) . to_string_lossy ( ) ; 
@@ -281,7 +282,27 @@ pub fn check(path: &Path, bad: &mut bool) {
281282        let  mut  trailing_new_lines = 0 ; 
282283        let  mut  lines = 0 ; 
283284        let  mut  last_safety_comment = false ; 
285+         let  is_test = file. components ( ) . any ( |c| c. as_os_str ( )  == "tests" ) ; 
286+         // scanning the whole file for multiple needles at once is more efficient than 
287+         // executing lines times needles separate searches. 
288+         let  any_problematic_line = problematic_regex. is_match ( contents) ; 
284289        for  ( i,  line)  in  contents. split ( '\n' ) . enumerate ( )  { 
290+             if  line. is_empty ( )  { 
291+                 if  i == 0  { 
292+                     leading_new_lines = true ; 
293+                 } 
294+                 trailing_new_lines += 1 ; 
295+                 continue ; 
296+             }  else  { 
297+                 trailing_new_lines = 0 ; 
298+             } 
299+ 
300+             let  trimmed = line. trim ( ) ; 
301+ 
302+             if  !trimmed. starts_with ( "//" )  { 
303+                 lines += 1 ; 
304+             } 
305+ 
285306            let  mut  err = |msg :  & str | { 
286307                tidy_error ! ( bad,  "{}:{}: {}" ,  file. display( ) ,  i + 1 ,  msg) ; 
287308            } ; 
@@ -308,36 +329,38 @@ pub fn check(path: &Path, bad: &mut bool) {
308329                suppressible_tidy_err ! ( err,  skip_cr,  "CR character" ) ; 
309330            } 
310331            if  filename != "style.rs"  { 
311-                 if  line . contains ( "TODO" )  { 
332+                 if  trimmed . contains ( "TODO" )  { 
312333                    err ( "TODO is deprecated; use FIXME" ) 
313334                } 
314-                 if  line . contains ( "//" )  && line . contains ( " XXX" )  { 
335+                 if  trimmed . contains ( "//" )  && trimmed . contains ( " XXX" )  { 
315336                    err ( "XXX is deprecated; use FIXME" ) 
316337                } 
317-                 for  s in  problematic_consts_strings. iter ( )  { 
318-                     if  line. contains ( s)  { 
319-                         err ( "Don't use magic numbers that spell things (consider 0x12345678)" ) ; 
338+                 if  any_problematic_line { 
339+                     for  s in  problematic_consts_strings. iter ( )  { 
340+                         if  trimmed. contains ( s)  { 
341+                             err ( "Don't use magic numbers that spell things (consider 0x12345678)" ) ; 
342+                         } 
320343                    } 
321344                } 
322345            } 
323-             let  is_test = || file. components ( ) . any ( |c| c. as_os_str ( )  == "tests" ) ; 
324346            // for now we just check libcore 
325-             if  line . contains ( "unsafe {" )  && !line . trim ( ) . starts_with ( "//" )  && !last_safety_comment { 
326-                 if  file. components ( ) . any ( |c| c. as_os_str ( )  == "core" )  && !is_test ( )  { 
347+             if  trimmed . contains ( "unsafe {" )  && !trimmed . starts_with ( "//" )  && !last_safety_comment { 
348+                 if  file. components ( ) . any ( |c| c. as_os_str ( )  == "core" )  && !is_test { 
327349                    suppressible_tidy_err ! ( err,  skip_undocumented_unsafe,  "undocumented unsafe" ) ; 
328350                } 
329351            } 
330-             if  line . contains ( "// SAFETY:" )  { 
352+             if  trimmed . contains ( "// SAFETY:" )  { 
331353                last_safety_comment = true ; 
332-             }  else  if  line . trim ( ) . starts_with ( "//" )  || line . trim ( ) . is_empty ( )  { 
354+             }  else  if  trimmed . starts_with ( "//" )  || trimmed . is_empty ( )  { 
333355                // keep previous value 
334356            }  else  { 
335357                last_safety_comment = false ; 
336358            } 
337359            if  ( line. starts_with ( "// Copyright" ) 
338360                || line. starts_with ( "# Copyright" ) 
339361                || line. starts_with ( "Copyright" ) ) 
340-                 && ( line. contains ( "Rust Developers" )  || line. contains ( "Rust Project Developers" ) ) 
362+                 && ( trimmed. contains ( "Rust Developers" ) 
363+                     || trimmed. contains ( "Rust Project Developers" ) ) 
341364            { 
342365                suppressible_tidy_err ! ( 
343366                    err, 
@@ -351,18 +374,6 @@ pub fn check(path: &Path, bad: &mut bool) {
351374            if  filename. ends_with ( ".cpp" )  && line. contains ( "llvm_unreachable" )  { 
352375                err ( LLVM_UNREACHABLE_INFO ) ; 
353376            } 
354-             if  line. is_empty ( )  { 
355-                 if  i == 0  { 
356-                     leading_new_lines = true ; 
357-                 } 
358-                 trailing_new_lines += 1 ; 
359-             }  else  { 
360-                 trailing_new_lines = 0 ; 
361-             } 
362- 
363-             if  !line. trim ( ) . starts_with ( "//" )  { 
364-                 lines += 1 ; 
365-             } 
366377        } 
367378        if  leading_new_lines { 
368379            let  mut  err = |_| { 
0 commit comments