@@ -14,7 +14,7 @@ use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
1414use crate :: header:: cfg:: parse_cfg_name_directive;
1515use crate :: header:: cfg:: MatchOutcome ;
1616use crate :: header:: needs:: CachedNeedsConditions ;
17- use crate :: util:: find_best_match_for_name;
17+ use crate :: util:: edit_distance :: find_best_match_for_name;
1818use crate :: { extract_cdb_version, extract_gdb_version} ;
1919
2020mod cfg;
@@ -673,8 +673,8 @@ pub fn line_directive<'line>(
673673/// This is generated by collecting directives from ui tests and then extracting their directive
674674/// names. This is **not** an exhaustive list of all possible directives. Instead, this is a
675675/// best-effort approximation for diagnostics.
676- // tidy-alphabetical-start
677676const KNOWN_DIRECTIVE_NAMES : & [ & str ] = & [
677+ // tidy-alphabetical-start
678678 "assembly-output" ,
679679 "aux-build" ,
680680 "aux-crate" ,
@@ -871,8 +871,8 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
871871 "unit-test" ,
872872 "unset-exec-env" ,
873873 "unset-rustc-env" ,
874+ // tidy-alphabetical-end
874875] ;
875- // tidy-alphabetical-end
876876
877877/// The broken-down contents of a line containing a test header directive,
878878/// which [`iter_header`] passes to its callback function.
@@ -902,6 +902,22 @@ struct HeaderLine<'ln> {
902902 directive : & ' ln str ,
903903}
904904
905+ pub ( crate ) struct CheckDirectiveResult < ' ln > {
906+ is_known_directive : bool ,
907+ directive_name : & ' ln str ,
908+ }
909+
910+ // Returns `(is_known_directive, directive_name)`.
911+ pub ( crate ) fn check_directive ( directive_ln : & str ) -> CheckDirectiveResult < ' _ > {
912+ let directive_name =
913+ directive_ln. split_once ( [ ':' , ' ' ] ) . map ( |( pre, _) | pre) . unwrap_or ( directive_ln) ;
914+
915+ CheckDirectiveResult {
916+ is_known_directive : KNOWN_DIRECTIVE_NAMES . contains ( & directive_name) ,
917+ directive_name : directive_ln,
918+ }
919+ }
920+
905921fn iter_header (
906922 mode : Mode ,
907923 _suite : & str ,
@@ -941,6 +957,7 @@ fn iter_header(
941957 let mut ln = String :: new ( ) ;
942958 let mut line_number = 0 ;
943959
960+ // Match on error annotations like `//~ERROR`.
944961 static REVISION_MAGIC_COMMENT_RE : Lazy < Regex > =
945962 Lazy :: new ( || Regex :: new ( "//(\\ [.*\\ ])?~.*" ) . unwrap ( ) ) ;
946963
@@ -959,33 +976,19 @@ fn iter_header(
959976 if ln. starts_with ( "fn" ) || ln. starts_with ( "mod" ) {
960977 return ;
961978
962- // First try to accept `ui_test` style comments
963- } else if let Some ( ( header_revision, original_directive_line) ) = line_directive ( comment, ln)
979+ // First try to accept `ui_test` style comments (`//@`)
980+ } else if let Some ( ( header_revision, non_revisioned_directive_line) ) =
981+ line_directive ( comment, ln)
964982 {
965- // Let Makefiles and non-rs files just get handled in the regular way.
966- if testfile. extension ( ) . map ( |e| e != "rs" ) . unwrap_or ( true ) {
967- it ( HeaderLine {
968- line_number,
969- original_line,
970- header_revision,
971- directive : original_directive_line,
972- } ) ;
973- continue ;
974- }
983+ // Perform unknown directive check on Rust files.
984+ if testfile. extension ( ) . map ( |e| e == "rs" ) . unwrap_or ( false ) {
985+ let directive_ln = non_revisioned_directive_line. trim ( ) ;
975986
976- let directive_ln = original_directive_line . trim ( ) ;
987+ let CheckDirectiveResult { is_known_directive , directive_name } = check_directive ( directive_ln ) ;
977988
978- if let Some ( ( directive_name, _) ) = directive_ln. split_once ( [ ':' , ' ' ] ) {
979- if KNOWN_DIRECTIVE_NAMES . contains ( & directive_name) {
980- it ( HeaderLine {
981- line_number,
982- original_line,
983- header_revision,
984- directive : original_directive_line,
985- } ) ;
986- continue ;
987- } else {
989+ if !is_known_directive {
988990 * poisoned = true ;
991+
989992 eprintln ! (
990993 "error: detected unknown compiletest test directive `{}` in {}:{}" ,
991994 directive_ln,
@@ -998,32 +1001,19 @@ fn iter_header(
9981001 {
9991002 eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
10001003 }
1001- return ;
1002- }
1003- } else if KNOWN_DIRECTIVE_NAMES . contains ( & directive_ln) {
1004- it ( HeaderLine {
1005- line_number,
1006- original_line,
1007- header_revision,
1008- directive : original_directive_line,
1009- } ) ;
1010- continue ;
1011- } else {
1012- * poisoned = true ;
1013- eprintln ! (
1014- "error: detected unknown compiletest test directive `{}` in {}:{}" ,
1015- directive_ln,
1016- testfile. display( ) ,
1017- line_number,
1018- ) ;
10191004
1020- if let Some ( suggestion) =
1021- find_best_match_for_name ( KNOWN_DIRECTIVE_NAMES , directive_ln, None )
1022- {
1023- eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
1005+ return ;
10241006 }
1025- return ;
10261007 }
1008+
1009+ it ( HeaderLine {
1010+ line_number,
1011+ original_line,
1012+ header_revision,
1013+ directive : non_revisioned_directive_line,
1014+ } ) ;
1015+ // Then we try to check for legacy-style candidates, which are not the magic ~ERROR family
1016+ // error annotations.
10271017 } else if !REVISION_MAGIC_COMMENT_RE . is_match ( ln) {
10281018 let Some ( ( _, rest) ) = line_directive ( "//" , ln) else {
10291019 continue ;
@@ -1037,34 +1027,18 @@ fn iter_header(
10371027
10381028 let rest = rest. trim_start ( ) ;
10391029
1040- for candidate in KNOWN_DIRECTIVE_NAMES . iter ( ) {
1041- if rest. starts_with ( candidate) {
1042- let Some ( prefix_removed) = rest. strip_prefix ( candidate) else {
1043- // We have a comment that's *successfully* parsed as an legacy-style
1044- // directive. We emit an error here to warn the user.
1045- * poisoned = true ;
1046- eprintln ! (
1047- "error: detected legacy-style directives in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead:{:#?}" ,
1048- testfile. display( ) ,
1049- line_number,
1050- line_directive( "//" , ln) ,
1051- ) ;
1052- return ;
1053- } ;
1030+ let CheckDirectiveResult { is_known_directive, directive_name } = check_directive ( rest) ;
10541031
1055- if prefix_removed. starts_with ( [ ' ' , ':' ] ) {
1056- // We have a comment that's *successfully* parsed as an legacy-style
1057- // directive. We emit an error here to warn the user.
1058- * poisoned = true ;
1059- eprintln ! (
1060- "error: detected legacy-style directives in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead:{:#?}" ,
1061- testfile. display( ) ,
1062- line_number,
1063- line_directive( "//" , ln) ,
1064- ) ;
1065- return ;
1066- }
1067- }
1032+ if is_known_directive {
1033+ * poisoned = true ;
1034+ eprintln ! (
1035+ "error: detected legacy-style directive {} in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead: {:#?}" ,
1036+ directive_name,
1037+ testfile. display( ) ,
1038+ line_number,
1039+ line_directive( "//" , ln) ,
1040+ ) ;
1041+ return ;
10681042 }
10691043 }
10701044 }
0 commit comments