@@ -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;
@@ -673,8 +673,8 @@ pub fn line_directive<'line>(
673
673
/// This is generated by collecting directives from ui tests and then extracting their directive
674
674
/// names. This is **not** an exhaustive list of all possible directives. Instead, this is a
675
675
/// best-effort approximation for diagnostics.
676
- // tidy-alphabetical-start
677
676
const KNOWN_DIRECTIVE_NAMES : & [ & str ] = & [
677
+ // tidy-alphabetical-start
678
678
"assembly-output" ,
679
679
"aux-build" ,
680
680
"aux-crate" ,
@@ -871,8 +871,8 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
871
871
"unit-test" ,
872
872
"unset-exec-env" ,
873
873
"unset-rustc-env" ,
874
+ // tidy-alphabetical-end
874
875
] ;
875
- // tidy-alphabetical-end
876
876
877
877
/// The broken-down contents of a line containing a test header directive,
878
878
/// which [`iter_header`] passes to its callback function.
@@ -902,6 +902,22 @@ struct HeaderLine<'ln> {
902
902
directive : & ' ln str ,
903
903
}
904
904
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
+
905
921
fn iter_header (
906
922
mode : Mode ,
907
923
_suite : & str ,
@@ -941,6 +957,7 @@ fn iter_header(
941
957
let mut ln = String :: new ( ) ;
942
958
let mut line_number = 0 ;
943
959
960
+ // Match on error annotations like `//~ERROR`.
944
961
static REVISION_MAGIC_COMMENT_RE : Lazy < Regex > =
945
962
Lazy :: new ( || Regex :: new ( "//(\\ [.*\\ ])?~.*" ) . unwrap ( ) ) ;
946
963
@@ -959,33 +976,19 @@ fn iter_header(
959
976
if ln. starts_with ( "fn" ) || ln. starts_with ( "mod" ) {
960
977
return ;
961
978
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)
964
982
{
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 ( ) ;
975
986
976
- let directive_ln = original_directive_line . trim ( ) ;
987
+ let CheckDirectiveResult { is_known_directive , directive_name } = check_directive ( directive_ln ) ;
977
988
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 {
988
990
* poisoned = true ;
991
+
989
992
eprintln ! (
990
993
"error: detected unknown compiletest test directive `{}` in {}:{}" ,
991
994
directive_ln,
@@ -998,32 +1001,19 @@ fn iter_header(
998
1001
{
999
1002
eprintln ! ( "help: did you mean `{}` instead?" , suggestion) ;
1000
1003
}
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
- ) ;
1019
1004
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 ;
1024
1006
}
1025
- return ;
1026
1007
}
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.
1027
1017
} else if !REVISION_MAGIC_COMMENT_RE . is_match ( ln) {
1028
1018
let Some ( ( _, rest) ) = line_directive ( "//" , ln) else {
1029
1019
continue ;
@@ -1037,34 +1027,18 @@ fn iter_header(
1037
1027
1038
1028
let rest = rest. trim_start ( ) ;
1039
1029
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) ;
1054
1031
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 ;
1068
1042
}
1069
1043
}
1070
1044
}
0 commit comments