@@ -835,9 +835,7 @@ fn check_directive<'a>(
835835 directive_ln : & DirectiveLine < ' a > ,
836836 mode : TestMode ,
837837) -> CheckDirectiveResult < ' a > {
838- let & DirectiveLine { raw_directive : directive_ln, .. } = directive_ln;
839-
840- let ( directive_name, post) = directive_ln. split_once ( [ ':' , ' ' ] ) . unwrap_or ( ( directive_ln, "" ) ) ;
838+ let & DirectiveLine { name : directive_name, .. } = directive_ln;
841839
842840 let is_known_directive = KNOWN_DIRECTIVE_NAMES . contains ( & directive_name)
843841 || match mode {
@@ -846,14 +844,13 @@ fn check_directive<'a>(
846844 _ => false ,
847845 } ;
848846
849- let trailing = post. trim ( ) . split_once ( ' ' ) . map ( |( pre, _) | pre) . unwrap_or ( post) ;
850- let trailing_directive = {
851- // 1. is the directive name followed by a space? (to exclude `:`)
852- directive_ln. get ( directive_name. len ( ) ..) . is_some_and ( |s| s. starts_with ( ' ' ) )
853- // 2. is what is after that directive also a directive (ex: "only-x86 only-arm")
854- && KNOWN_DIRECTIVE_NAMES . contains ( & trailing)
855- }
856- . then_some ( trailing) ;
847+ // If it looks like the user tried to put two directives on the same line
848+ // (e.g. `//@ only-linux only-x86_64`), signal an error, because the
849+ // second "directive" would actually be ignored with no effect.
850+ let trailing_directive = directive_ln
851+ . remark_after_space ( )
852+ . map ( |remark| remark. trim_start ( ) . split ( ' ' ) . next ( ) . unwrap ( ) )
853+ . filter ( |token| KNOWN_DIRECTIVE_NAMES . contains ( token) ) ;
857854
858855 CheckDirectiveResult { is_known_directive, trailing_directive }
859856}
@@ -915,7 +912,7 @@ fn iter_directives(
915912
916913 error ! (
917914 "{testfile}:{line_number}: detected unknown compiletest test directive `{}`" ,
918- directive_line. raw_directive ,
915+ directive_line. display ( ) ,
919916 ) ;
920917
921918 return ;
@@ -1011,35 +1008,30 @@ impl Config {
10111008 }
10121009
10131010 fn parse_custom_normalization ( & self , line : & DirectiveLine < ' _ > ) -> Option < NormalizeRule > {
1014- let & DirectiveLine { raw_directive, .. } = line;
1015-
1016- // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine`
1017- // instead of doing it here.
1018- let ( directive_name, raw_value) = raw_directive. split_once ( ':' ) ?;
1011+ let & DirectiveLine { name, .. } = line;
10191012
1020- let kind = match directive_name {
1013+ let kind = match name {
10211014 "normalize-stdout" => NormalizeKind :: Stdout ,
10221015 "normalize-stderr" => NormalizeKind :: Stderr ,
10231016 "normalize-stderr-32bit" => NormalizeKind :: Stderr32bit ,
10241017 "normalize-stderr-64bit" => NormalizeKind :: Stderr64bit ,
10251018 _ => return None ,
10261019 } ;
10271020
1028- let Some ( ( regex, replacement) ) = parse_normalize_rule ( raw_value) else {
1029- error ! ( "couldn't parse custom normalization rule: `{raw_directive}`" ) ;
1030- help ! ( "expected syntax is: `{directive_name}: \" REGEX\" -> \" REPLACEMENT\" `" ) ;
1021+ let Some ( ( regex, replacement) ) = line. value_after_colon ( ) . and_then ( parse_normalize_rule)
1022+ else {
1023+ error ! ( "couldn't parse custom normalization rule: `{}`" , line. display( ) ) ;
1024+ help ! ( "expected syntax is: `{name}: \" REGEX\" -> \" REPLACEMENT\" `" ) ;
10311025 panic ! ( "invalid normalization rule detected" ) ;
10321026 } ;
10331027 Some ( NormalizeRule { kind, regex, replacement } )
10341028 }
10351029
10361030 fn parse_name_directive ( & self , line : & DirectiveLine < ' _ > , directive : & str ) -> bool {
1037- let & DirectiveLine { raw_directive : line, .. } = line;
1038-
1039- // Ensure the directive is a whole word. Do not match "ignore-x86" when
1040- // the line says "ignore-x86_64".
1041- line. starts_with ( directive)
1042- && matches ! ( line. as_bytes( ) . get( directive. len( ) ) , None | Some ( & b' ' ) | Some ( & b':' ) )
1031+ // FIXME(Zalathar): Ideally, this should raise an error if a name-only
1032+ // directive is followed by a colon, since that's the wrong syntax.
1033+ // But we would need to fix tests that rely on the current behaviour.
1034+ line. name == directive
10431035 }
10441036
10451037 fn parse_name_value_directive (
@@ -1048,22 +1040,26 @@ impl Config {
10481040 directive : & str ,
10491041 testfile : & Utf8Path ,
10501042 ) -> Option < String > {
1051- let & DirectiveLine { line_number, raw_directive : line, .. } = line;
1052-
1053- let colon = directive. len ( ) ;
1054- if line. starts_with ( directive) && line. as_bytes ( ) . get ( colon) == Some ( & b':' ) {
1055- let value = line[ ( colon + 1 ) ..] . to_owned ( ) ;
1056- debug ! ( "{}: {}" , directive, value) ;
1057- let value = expand_variables ( value, self ) ;
1058- if value. is_empty ( ) {
1059- error ! ( "{testfile}:{line_number}: empty value for directive `{directive}`" ) ;
1060- help ! ( "expected syntax is: `{directive}: value`" ) ;
1061- panic ! ( "empty directive value detected" ) ;
1062- }
1063- Some ( value)
1064- } else {
1065- None
1043+ let & DirectiveLine { line_number, .. } = line;
1044+
1045+ if line. name != directive {
1046+ return None ;
1047+ } ;
1048+
1049+ // FIXME(Zalathar): This silently discards directives with a matching
1050+ // name but no colon. Unfortunately, some directives (e.g. "pp-exact")
1051+ // currently rely on _not_ panicking here.
1052+ let value = line. value_after_colon ( ) ?;
1053+ debug ! ( "{}: {}" , directive, value) ;
1054+ let value = expand_variables ( value. to_owned ( ) , self ) ;
1055+
1056+ if value. is_empty ( ) {
1057+ error ! ( "{testfile}:{line_number}: empty value for directive `{directive}`" ) ;
1058+ help ! ( "expected syntax is: `{directive}: value`" ) ;
1059+ panic ! ( "empty directive value detected" ) ;
10661060 }
1061+
1062+ Some ( value)
10671063 }
10681064
10691065 fn set_name_directive ( & self , line : & DirectiveLine < ' _ > , directive : & str , value : & mut bool ) {
@@ -1453,14 +1449,14 @@ pub(crate) fn make_test_description<R: Read>(
14531449}
14541450
14551451fn ignore_cdb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1456- let & DirectiveLine { raw_directive : line, .. } = line;
1457-
14581452 if config. debugger != Some ( Debugger :: Cdb ) {
14591453 return IgnoreDecision :: Continue ;
14601454 }
14611455
14621456 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+ {
14641460 let min_version = extract_cdb_version ( rest) . unwrap_or_else ( || {
14651461 panic ! ( "couldn't parse version range: {:?}" , rest) ;
14661462 } ) ;
@@ -1478,14 +1474,14 @@ fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
14781474}
14791475
14801476fn ignore_gdb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1481- let & DirectiveLine { raw_directive : line, .. } = line;
1482-
14831477 if config. debugger != Some ( Debugger :: Gdb ) {
14841478 return IgnoreDecision :: Continue ;
14851479 }
14861480
14871481 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+ {
14891485 let ( start_ver, end_ver) = extract_version_range ( rest, extract_gdb_version)
14901486 . unwrap_or_else ( || {
14911487 panic ! ( "couldn't parse version range: {:?}" , rest) ;
@@ -1501,7 +1497,9 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
15011497 reason : format ! ( "ignored when the GDB version is lower than {rest}" ) ,
15021498 } ;
15031499 }
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+ {
15051503 let ( min_version, max_version) = extract_version_range ( rest, extract_gdb_version)
15061504 . unwrap_or_else ( || {
15071505 panic ! ( "couldn't parse version range: {:?}" , rest) ;
@@ -1528,14 +1526,14 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
15281526}
15291527
15301528fn ignore_lldb ( config : & Config , line : & DirectiveLine < ' _ > ) -> IgnoreDecision {
1531- let & DirectiveLine { raw_directive : line, .. } = line;
1532-
15331529 if config. debugger != Some ( Debugger :: Lldb ) {
15341530 return IgnoreDecision :: Continue ;
15351531 }
15361532
15371533 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+ {
15391537 let min_version = rest. parse ( ) . unwrap_or_else ( |e| {
15401538 panic ! ( "Unexpected format of LLDB version string: {}\n {:?}" , rest, e) ;
15411539 } ) ;
0 commit comments