Skip to content

Commit 6783e94

Browse files
committed
Allow easy extraction of name/value from a DirectiveLine
1 parent 757d98c commit 6783e94

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/tools/compiletest/src/directives.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -875,15 +875,17 @@ fn iter_directives(
875875
// FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later.
876876
if mode == TestMode::CoverageRun {
877877
let extra_directives: &[&str] = &[
878-
"needs-profiler-runtime",
878+
"//@ needs-profiler-runtime",
879879
// FIXME(pietroalbini): this test currently does not work on cross-compiled targets
880880
// because remote-test is not capable of sending back the *.profraw files generated by
881881
// the LLVM instrumentation.
882-
"ignore-cross-compile",
882+
"//@ ignore-cross-compile",
883883
];
884884
// Process the extra implied directives, with a dummy line number of 0.
885-
for raw_directive in extra_directives {
886-
it(DirectiveLine { line_number: 0, revision: None, raw_directive });
885+
for directive_str in extra_directives {
886+
let directive_line = line_directive(0, directive_str)
887+
.unwrap_or_else(|| panic!("bad extra-directive line: {directive_str:?}"));
888+
it(directive_line);
887889
}
888890
}
889891

src/tools/compiletest/src/directives/line.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#![expect(dead_code)] // (removed later in this PR)
2+
3+
use std::fmt;
4+
15
const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
26

37
/// If the given line begins with the appropriate comment prefix for a directive,
@@ -28,7 +32,10 @@ pub(crate) fn line_directive<'line>(
2832
raw_directive = after_comment;
2933
};
3034

31-
Some(DirectiveLine { line_number, revision, raw_directive })
35+
// The directive name ends at the first occurrence of colon, space, or end-of-string.
36+
let name = raw_directive.split([':', ' ']).next().expect("split is never empty");
37+
38+
Some(DirectiveLine { line_number, revision, raw_directive, name })
3239
}
3340

3441
/// The (partly) broken-down contents of a line containing a test directive,
@@ -39,10 +46,12 @@ pub(crate) fn line_directive<'line>(
3946
/// ```text
4047
/// //@ compile-flags: -O
4148
/// ^^^^^^^^^^^^^^^^^ raw_directive
49+
/// ^^^^^^^^^^^^^ name
4250
///
4351
/// //@ [foo] compile-flags: -O
4452
/// ^^^ revision
4553
/// ^^^^^^^^^^^^^^^^^ raw_directive
54+
/// ^^^^^^^^^^^^^ name
4655
/// ```
4756
pub(crate) struct DirectiveLine<'ln> {
4857
pub(crate) line_number: usize,
@@ -58,10 +67,44 @@ pub(crate) struct DirectiveLine<'ln> {
5867
/// This is "raw" because the directive's name and colon-separated value
5968
/// (if present) have not yet been extracted or checked.
6069
pub(crate) raw_directive: &'ln str,
70+
71+
/// Name of the directive.
72+
///
73+
/// Invariant: `self.raw_directive.starts_with(self.name)`
74+
pub(crate) name: &'ln str,
6175
}
6276

6377
impl<'ln> DirectiveLine<'ln> {
6478
pub(crate) fn applies_to_test_revision(&self, test_revision: Option<&str>) -> bool {
6579
self.revision.is_none() || self.revision == test_revision
6680
}
81+
82+
/// Helper method used by `value_after_colon` and `remark_after_space`.
83+
/// Don't call this directly.
84+
fn rest_after_separator(&self, separator: u8) -> Option<&'ln str> {
85+
let n = self.name.len();
86+
if self.raw_directive.as_bytes().get(n) != Some(&separator) {
87+
return None;
88+
}
89+
90+
Some(&self.raw_directive[n + 1..])
91+
}
92+
93+
/// If this directive uses `name: value` syntax, returns the part after
94+
/// the colon character.
95+
pub(crate) fn value_after_colon(&self) -> Option<&'ln str> {
96+
self.rest_after_separator(b':')
97+
}
98+
99+
/// If this directive uses `name remark` syntax, returns the part after
100+
/// the separating space.
101+
pub(crate) fn remark_after_space(&self) -> Option<&'ln str> {
102+
self.rest_after_separator(b' ')
103+
}
104+
105+
/// Allows callers to print `raw_directive` if necessary,
106+
/// without accessing the field directly.
107+
pub(crate) fn display(&self) -> impl fmt::Display {
108+
self.raw_directive
109+
}
67110
}

0 commit comments

Comments
 (0)