@@ -831,9 +831,7 @@ fn check_directive<'a>(
831
831
directive_ln : & DirectiveLine < ' a > ,
832
832
mode : TestMode ,
833
833
) -> CheckDirectiveResult < ' a > {
834
- let & DirectiveLine { raw_directive : directive_ln, .. } = directive_ln;
835
-
836
- let ( directive_name, post) = directive_ln. split_once ( [ ':' , ' ' ] ) . unwrap_or ( ( directive_ln, "" ) ) ;
834
+ let & DirectiveLine { name : directive_name, .. } = directive_ln;
837
835
838
836
let is_known_directive = KNOWN_DIRECTIVE_NAMES . contains ( & directive_name)
839
837
|| match mode {
@@ -842,14 +840,13 @@ fn check_directive<'a>(
842
840
_ => false ,
843
841
} ;
844
842
845
- let trailing = post. trim ( ) . split_once ( ' ' ) . map ( |( pre, _) | pre) . unwrap_or ( post) ;
846
- let trailing_directive = {
847
- // 1. is the directive name followed by a space? (to exclude `:`)
848
- directive_ln. get ( directive_name. len ( ) ..) . is_some_and ( |s| s. starts_with ( ' ' ) )
849
- // 2. is what is after that directive also a directive (ex: "only-x86 only-arm")
850
- && KNOWN_DIRECTIVE_NAMES . contains ( & trailing)
851
- }
852
- . then_some ( trailing) ;
843
+ // If it looks like the user tried to put two directives on the same line
844
+ // (e.g. `//@ only-linux only-x86_64`), signal an error, because the
845
+ // second "directive" would actually be ignored with no effect.
846
+ let trailing_directive = directive_ln
847
+ . remark_after_space ( )
848
+ . map ( |remark| remark. trim_start ( ) . split ( ' ' ) . next ( ) . unwrap ( ) )
849
+ . filter ( |token| KNOWN_DIRECTIVE_NAMES . contains ( token) ) ;
853
850
854
851
CheckDirectiveResult { is_known_directive, trailing_directive }
855
852
}
@@ -911,7 +908,7 @@ fn iter_directives(
911
908
912
909
error ! (
913
910
"{testfile}:{line_number}: detected unknown compiletest test directive `{}`" ,
914
- directive_line. raw_directive ,
911
+ directive_line. display ( ) ,
915
912
) ;
916
913
917
914
return ;
@@ -1007,35 +1004,30 @@ impl Config {
1007
1004
}
1008
1005
1009
1006
fn parse_custom_normalization ( & self , line : & DirectiveLine < ' _ > ) -> Option < NormalizeRule > {
1010
- let & DirectiveLine { raw_directive, .. } = line;
1011
-
1012
- // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine`
1013
- // instead of doing it here.
1014
- let ( directive_name, raw_value) = raw_directive. split_once ( ':' ) ?;
1007
+ let & DirectiveLine { name, .. } = line;
1015
1008
1016
- let kind = match directive_name {
1009
+ let kind = match name {
1017
1010
"normalize-stdout" => NormalizeKind :: Stdout ,
1018
1011
"normalize-stderr" => NormalizeKind :: Stderr ,
1019
1012
"normalize-stderr-32bit" => NormalizeKind :: Stderr32bit ,
1020
1013
"normalize-stderr-64bit" => NormalizeKind :: Stderr64bit ,
1021
1014
_ => return None ,
1022
1015
} ;
1023
1016
1024
- let Some ( ( regex, replacement) ) = parse_normalize_rule ( raw_value) else {
1025
- error ! ( "couldn't parse custom normalization rule: `{raw_directive}`" ) ;
1026
- help ! ( "expected syntax is: `{directive_name}: \" REGEX\" -> \" REPLACEMENT\" `" ) ;
1017
+ let Some ( ( regex, replacement) ) = line. value_after_colon ( ) . and_then ( parse_normalize_rule)
1018
+ else {
1019
+ error ! ( "couldn't parse custom normalization rule: `{}`" , line. display( ) ) ;
1020
+ help ! ( "expected syntax is: `{name}: \" REGEX\" -> \" REPLACEMENT\" `" ) ;
1027
1021
panic ! ( "invalid normalization rule detected" ) ;
1028
1022
} ;
1029
1023
Some ( NormalizeRule { kind, regex, replacement } )
1030
1024
}
1031
1025
1032
1026
fn parse_name_directive ( & self , line : & DirectiveLine < ' _ > , directive : & str ) -> bool {
1033
- let & DirectiveLine { raw_directive : line, .. } = line;
1034
-
1035
- // Ensure the directive is a whole word. Do not match "ignore-x86" when
1036
- // the line says "ignore-x86_64".
1037
- line. starts_with ( directive)
1038
- && matches ! ( line. as_bytes( ) . get( directive. len( ) ) , None | Some ( & b' ' ) | Some ( & b':' ) )
1027
+ // FIXME(Zalathar): Ideally, this should raise an error if a name-only
1028
+ // directive is followed by a colon, since that's the wrong syntax.
1029
+ // But we would need to fix tests that rely on the current behaviour.
1030
+ line. name == directive
1039
1031
}
1040
1032
1041
1033
fn parse_name_value_directive (
@@ -1044,22 +1036,26 @@ impl Config {
1044
1036
directive : & str ,
1045
1037
testfile : & Utf8Path ,
1046
1038
) -> Option < String > {
1047
- let & DirectiveLine { line_number, raw_directive : line, .. } = line;
1048
-
1049
- let colon = directive. len ( ) ;
1050
- if line. starts_with ( directive) && line. as_bytes ( ) . get ( colon) == Some ( & b':' ) {
1051
- let value = line[ ( colon + 1 ) ..] . to_owned ( ) ;
1052
- debug ! ( "{}: {}" , directive, value) ;
1053
- let value = expand_variables ( value, self ) ;
1054
- if value. is_empty ( ) {
1055
- error ! ( "{testfile}:{line_number}: empty value for directive `{directive}`" ) ;
1056
- help ! ( "expected syntax is: `{directive}: value`" ) ;
1057
- panic ! ( "empty directive value detected" ) ;
1058
- }
1059
- Some ( value)
1060
- } else {
1061
- None
1039
+ let & DirectiveLine { line_number, .. } = line;
1040
+
1041
+ if line. name != directive {
1042
+ return None ;
1043
+ } ;
1044
+
1045
+ // FIXME(Zalathar): This silently discards directives with a matching
1046
+ // name but no colon. Unfortunately, some directives (e.g. "pp-exact")
1047
+ // currently rely on _not_ panicking here.
1048
+ let value = line. value_after_colon ( ) ?;
1049
+ debug ! ( "{}: {}" , directive, value) ;
1050
+ let value = expand_variables ( value. to_owned ( ) , self ) ;
1051
+
1052
+ if value. is_empty ( ) {
1053
+ error ! ( "{testfile}:{line_number}: empty value for directive `{directive}`" ) ;
1054
+ help ! ( "expected syntax is: `{directive}: value`" ) ;
1055
+ panic ! ( "empty directive value detected" ) ;
1062
1056
}
1057
+
1058
+ Some ( value)
1063
1059
}
1064
1060
1065
1061
fn parse_edition ( & self , line : & DirectiveLine < ' _ > , testfile : & Utf8Path ) -> Option < String > {
@@ -1453,14 +1449,14 @@ pub(crate) fn make_test_description<R: Read>(
1453
1449
}
1454
1450
1455
1451
fn ignore_cdb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1456
- let & DirectiveLine { raw_directive : line, .. } = line;
1457
-
1458
1452
if config. debugger != Some ( Debugger :: Cdb ) {
1459
1453
return IgnoreDecision :: Continue ;
1460
1454
}
1461
1455
1462
1456
if let Some ( actual_version) = config. cdb_version {
1463
- if let Some ( rest) = line. strip_prefix ( "min-cdb-version:" ) . map ( str:: trim) {
1457
+ if line. name == "min-cdb-version"
1458
+ && let Some ( rest) = line. value_after_colon ( ) . map ( str:: trim)
1459
+ {
1464
1460
let min_version = extract_cdb_version ( rest) . unwrap_or_else ( || {
1465
1461
panic ! ( "couldn't parse version range: {:?}" , rest) ;
1466
1462
} ) ;
@@ -1478,14 +1474,14 @@ fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
1478
1474
}
1479
1475
1480
1476
fn ignore_gdb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1481
- let & DirectiveLine { raw_directive : line, .. } = line;
1482
-
1483
1477
if config. debugger != Some ( Debugger :: Gdb ) {
1484
1478
return IgnoreDecision :: Continue ;
1485
1479
}
1486
1480
1487
1481
if let Some ( actual_version) = config. gdb_version {
1488
- if let Some ( rest) = line. strip_prefix ( "min-gdb-version:" ) . map ( str:: trim) {
1482
+ if line. name == "min-gdb-version"
1483
+ && let Some ( rest) = line. value_after_colon ( ) . map ( str:: trim)
1484
+ {
1489
1485
let ( start_ver, end_ver) = extract_version_range ( rest, extract_gdb_version)
1490
1486
. unwrap_or_else ( || {
1491
1487
panic ! ( "couldn't parse version range: {:?}" , rest) ;
@@ -1501,7 +1497,9 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
1501
1497
reason : format ! ( "ignored when the GDB version is lower than {rest}" ) ,
1502
1498
} ;
1503
1499
}
1504
- } else if let Some ( rest) = line. strip_prefix ( "ignore-gdb-version:" ) . map ( str:: trim) {
1500
+ } else if line. name == "ignore-gdb-version"
1501
+ && let Some ( rest) = line. value_after_colon ( ) . map ( str:: trim)
1502
+ {
1505
1503
let ( min_version, max_version) = extract_version_range ( rest, extract_gdb_version)
1506
1504
. unwrap_or_else ( || {
1507
1505
panic ! ( "couldn't parse version range: {:?}" , rest) ;
@@ -1528,14 +1526,14 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
1528
1526
}
1529
1527
1530
1528
fn ignore_lldb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1531
- let & DirectiveLine { raw_directive : line, .. } = line;
1532
-
1533
1529
if config. debugger != Some ( Debugger :: Lldb ) {
1534
1530
return IgnoreDecision :: Continue ;
1535
1531
}
1536
1532
1537
1533
if let Some ( actual_version) = config. lldb_version {
1538
- if let Some ( rest) = line. strip_prefix ( "min-lldb-version:" ) . map ( str:: trim) {
1534
+ if line. name == "min-lldb-version"
1535
+ && let Some ( rest) = line. value_after_colon ( ) . map ( str:: trim)
1536
+ {
1539
1537
let min_version = rest. parse ( ) . unwrap_or_else ( |e| {
1540
1538
panic ! ( "Unexpected format of LLDB version string: {}\n {:?}" , rest, e) ;
1541
1539
} ) ;
0 commit comments