@@ -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;
@@ -681,8 +681,8 @@ pub fn line_directive<'line>(
681681/// This is generated by collecting directives from ui tests and then extracting their directive
682682/// names. This is **not** an exhaustive list of all possible directives. Instead, this is a
683683/// best-effort approximation for diagnostics.
684- // tidy-alphabetical-start
685684const KNOWN_DIRECTIVE_NAMES : & [ & str ] = & [
685+ // tidy-alphabetical-start
686686 "assembly-output" ,
687687 "aux-build" ,
688688 "aux-crate" ,
@@ -880,8 +880,8 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
880880 "unit-test" ,
881881 "unset-exec-env" ,
882882 "unset-rustc-env" ,
883+ // tidy-alphabetical-end
883884] ;
884- // tidy-alphabetical-end
885885
886886/// The broken-down contents of a line containing a test header directive,
887887/// which [`iter_header`] passes to its callback function.
@@ -911,6 +911,22 @@ struct HeaderLine<'ln> {
911911 directive : & ' ln str ,
912912}
913913
914+ pub ( crate ) struct CheckDirectiveResult < ' ln > {
915+ is_known_directive : bool ,
916+ directive_name : & ' ln str ,
917+ }
918+
919+ // Returns `(is_known_directive, directive_name)`.
920+ pub ( crate ) fn check_directive ( directive_ln : & str ) -> CheckDirectiveResult < ' _ > {
921+ let directive_name =
922+ directive_ln. split_once ( [ ':' , ' ' ] ) . map ( |( pre, _) | pre) . unwrap_or ( directive_ln) ;
923+
924+ CheckDirectiveResult {
925+ is_known_directive : KNOWN_DIRECTIVE_NAMES . contains ( & directive_name) ,
926+ directive_name : directive_ln,
927+ }
928+ }
929+
914930fn iter_header (
915931 mode : Mode ,
916932 _suite : & str ,
@@ -950,6 +966,7 @@ fn iter_header(
950966 let mut ln = String :: new ( ) ;
951967 let mut line_number = 0 ;
952968
969+ // Match on error annotations like `//~ERROR`.
953970 static REVISION_MAGIC_COMMENT_RE : Lazy < Regex > =
954971 Lazy :: new ( || Regex :: new ( "//(\\ [.*\\ ])?~.*" ) . unwrap ( ) ) ;
955972
@@ -968,33 +985,19 @@ fn iter_header(
968985 if ln. starts_with ( "fn" ) || ln. starts_with ( "mod" ) {
969986 return ;
970987
971- // First try to accept `ui_test` style comments
972- } else if let Some ( ( header_revision, original_directive_line) ) = line_directive ( comment, ln)
988+ // First try to accept `ui_test` style comments (`//@`)
989+ } else if let Some ( ( header_revision, non_revisioned_directive_line) ) =
990+ line_directive ( comment, ln)
973991 {
974- // Let Makefiles and non-rs files just get handled in the regular way.
975- if testfile. extension ( ) . map ( |e| e != "rs" ) . unwrap_or ( true ) {
976- it ( HeaderLine {
977- line_number,
978- original_line,
979- header_revision,
980- directive : original_directive_line,
981- } ) ;
982- continue ;
983- }
992+ // Perform unknown directive check on Rust files.
993+ if testfile. extension ( ) . map ( |e| e == "rs" ) . unwrap_or ( false ) {
994+ let directive_ln = non_revisioned_directive_line. trim ( ) ;
984995
985- let directive_ln = original_directive_line . trim ( ) ;
996+ let CheckDirectiveResult { is_known_directive , directive_name } = check_directive ( directive_ln ) ;
986997
987- if let Some ( ( directive_name, _) ) = directive_ln. split_once ( [ ':' , ' ' ] ) {
988- if KNOWN_DIRECTIVE_NAMES . contains ( & directive_name) {
989- it ( HeaderLine {
990- line_number,
991- original_line,
992- header_revision,
993- directive : original_directive_line,
994- } ) ;
995- continue ;
996- } else {
998+ if !is_known_directive {
997999 * poisoned = true ;
1000+
9981001 eprintln ! (
9991002 "error: detected unknown compiletest test directive `{}` in {}:{}" ,
10001003 directive_ln,
@@ -1007,32 +1010,19 @@ fn iter_header(
10071010 {
10081011 eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
10091012 }
1010- return ;
1011- }
1012- } else if KNOWN_DIRECTIVE_NAMES . contains ( & directive_ln) {
1013- it ( HeaderLine {
1014- line_number,
1015- original_line,
1016- header_revision,
1017- directive : original_directive_line,
1018- } ) ;
1019- continue ;
1020- } else {
1021- * poisoned = true ;
1022- eprintln ! (
1023- "error: detected unknown compiletest test directive `{}` in {}:{}" ,
1024- directive_ln,
1025- testfile. display( ) ,
1026- line_number,
1027- ) ;
10281013
1029- if let Some ( suggestion) =
1030- find_best_match_for_name ( KNOWN_DIRECTIVE_NAMES , directive_ln, None )
1031- {
1032- eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
1014+ return ;
10331015 }
1034- return ;
10351016 }
1017+
1018+ it ( HeaderLine {
1019+ line_number,
1020+ original_line,
1021+ header_revision,
1022+ directive : non_revisioned_directive_line,
1023+ } ) ;
1024+ // Then we try to check for legacy-style candidates, which are not the magic ~ERROR family
1025+ // error annotations.
10361026 } else if !REVISION_MAGIC_COMMENT_RE . is_match ( ln) {
10371027 let Some ( ( _, rest) ) = line_directive ( "//" , ln) else {
10381028 continue ;
@@ -1046,34 +1036,18 @@ fn iter_header(
10461036
10471037 let rest = rest. trim_start ( ) ;
10481038
1049- for candidate in KNOWN_DIRECTIVE_NAMES . iter ( ) {
1050- if rest. starts_with ( candidate) {
1051- let Some ( prefix_removed) = rest. strip_prefix ( candidate) else {
1052- // We have a comment that's *successfully* parsed as an legacy-style
1053- // directive. We emit an error here to warn the user.
1054- * poisoned = true ;
1055- eprintln ! (
1056- "error: detected legacy-style directives in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead:{:#?}" ,
1057- testfile. display( ) ,
1058- line_number,
1059- line_directive( "//" , ln) ,
1060- ) ;
1061- return ;
1062- } ;
1039+ let CheckDirectiveResult { is_known_directive, directive_name } = check_directive ( rest) ;
10631040
1064- if prefix_removed. starts_with ( [ ' ' , ':' ] ) {
1065- // We have a comment that's *successfully* parsed as an legacy-style
1066- // directive. We emit an error here to warn the user.
1067- * poisoned = true ;
1068- eprintln ! (
1069- "error: detected legacy-style directives in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead:{:#?}" ,
1070- testfile. display( ) ,
1071- line_number,
1072- line_directive( "//" , ln) ,
1073- ) ;
1074- return ;
1075- }
1076- }
1041+ if is_known_directive {
1042+ * poisoned = true ;
1043+ eprintln ! (
1044+ "error: detected legacy-style directive {} in compiletest test: {}:{}, please use `ui_test`-style directives `//@` instead: {:#?}" ,
1045+ directive_name,
1046+ testfile. display( ) ,
1047+ line_number,
1048+ line_directive( "//" , ln) ,
1049+ ) ;
1050+ return ;
10771051 }
10781052 }
10791053 }
0 commit comments