@@ -14,7 +14,7 @@ use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
14
14
use crate :: header:: cfg:: parse_cfg_name_directive;
15
15
use crate :: header:: cfg:: MatchOutcome ;
16
16
use crate :: header:: needs:: CachedNeedsConditions ;
17
- use crate :: util:: find_best_match_for_name;
17
+ use crate :: util:: edit_distance :: find_best_match_for_name;
18
18
use crate :: { extract_cdb_version, extract_gdb_version} ;
19
19
20
20
mod cfg;
@@ -681,8 +681,8 @@ pub fn line_directive<'line>(
681
681
/// This is generated by collecting directives from ui tests and then extracting their directive
682
682
/// names. This is **not** an exhaustive list of all possible directives. Instead, this is a
683
683
/// best-effort approximation for diagnostics.
684
- // tidy-alphabetical-start
685
684
const KNOWN_DIRECTIVE_NAMES : & [ & str ] = & [
685
+ // tidy-alphabetical-start
686
686
"assembly-output" ,
687
687
"aux-build" ,
688
688
"aux-crate" ,
@@ -880,8 +880,8 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
880
880
"unit-test" ,
881
881
"unset-exec-env" ,
882
882
"unset-rustc-env" ,
883
+ // tidy-alphabetical-end
883
884
] ;
884
- // tidy-alphabetical-end
885
885
886
886
/// The broken-down contents of a line containing a test header directive,
887
887
/// which [`iter_header`] passes to its callback function.
@@ -911,6 +911,22 @@ struct HeaderLine<'ln> {
911
911
directive : & ' ln str ,
912
912
}
913
913
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
+
914
930
fn iter_header (
915
931
mode : Mode ,
916
932
_suite : & str ,
@@ -950,6 +966,7 @@ fn iter_header(
950
966
let mut ln = String :: new ( ) ;
951
967
let mut line_number = 0 ;
952
968
969
+ // Match on error annotations like `//~ERROR`.
953
970
static REVISION_MAGIC_COMMENT_RE : Lazy < Regex > =
954
971
Lazy :: new ( || Regex :: new ( "//(\\ [.*\\ ])?~.*" ) . unwrap ( ) ) ;
955
972
@@ -968,33 +985,19 @@ fn iter_header(
968
985
if ln. starts_with ( "fn" ) || ln. starts_with ( "mod" ) {
969
986
return ;
970
987
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)
973
991
{
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 ( ) ;
984
995
985
- let directive_ln = original_directive_line . trim ( ) ;
996
+ let CheckDirectiveResult { is_known_directive , directive_name } = check_directive ( directive_ln ) ;
986
997
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 {
997
999
* poisoned = true ;
1000
+
998
1001
eprintln ! (
999
1002
"error: detected unknown compiletest test directive `{}` in {}:{}" ,
1000
1003
directive_ln,
@@ -1007,32 +1010,19 @@ fn iter_header(
1007
1010
{
1008
1011
eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
1009
1012
}
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
- ) ;
1028
1013
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 ;
1033
1015
}
1034
- return ;
1035
1016
}
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.
1036
1026
} else if !REVISION_MAGIC_COMMENT_RE . is_match ( ln) {
1037
1027
let Some ( ( _, rest) ) = line_directive ( "//" , ln) else {
1038
1028
continue ;
@@ -1046,34 +1036,18 @@ fn iter_header(
1046
1036
1047
1037
let rest = rest. trim_start ( ) ;
1048
1038
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) ;
1063
1040
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 ;
1077
1051
}
1078
1052
}
1079
1053
}
0 commit comments