Skip to content

Commit 602a934

Browse files
authored
Unrolled build for rust-lang#121373
Rollup merge of rust-lang#121373 - Zalathar:test-revision, r=oli-obk Consistently refer to a test's `revision` instead of `cfg` Compiletest allows a test file to specify multiple “revisions” (`//@ revisions: foo bar`), with each revision running as a separate test, and having the ability to define revision-specific headers (`//`@[foo]` ignore-blah`) and revision-specific code (`#[cfg(foo)]`). The code that implements this feature sometimes uses the term “cfg” instead of “revision”. This results in two confusingly-different names for the same concept, one of which is ambiguous with other kinds of configuration (such as compiletest's own config). This PR replaces those occurrences of `cfg` with `revision`, so that one name is used consistently.
2 parents 3406ada + 544d091 commit 602a934

File tree

4 files changed

+81
-65
lines changed

4 files changed

+81
-65
lines changed

src/tools/compiletest/src/errors.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ enum WhichLine {
7272
/// and also //~^ ERROR message one for the preceding line, and
7373
/// //~| ERROR message two for that same line.
7474
///
75-
/// If cfg is not None (i.e., in an incremental test), then we look
76-
/// for `//[X]~` instead, where `X` is the current `cfg`.
77-
pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<Error> {
75+
/// If revision is not None, then we look
76+
/// for `//[X]~` instead, where `X` is the current revision.
77+
pub fn load_errors(testfile: &Path, revision: Option<&str>) -> Vec<Error> {
7878
let rdr = BufReader::new(File::open(testfile).unwrap());
7979

8080
// `last_nonfollow_error` tracks the most recently seen
@@ -90,7 +90,7 @@ pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<Error> {
9090
rdr.lines()
9191
.enumerate()
9292
.filter_map(|(line_num, line)| {
93-
parse_expected(last_nonfollow_error, line_num + 1, &line.unwrap(), cfg).map(
93+
parse_expected(last_nonfollow_error, line_num + 1, &line.unwrap(), revision).map(
9494
|(which, error)| {
9595
match which {
9696
FollowPrevious(_) => {}
@@ -108,24 +108,27 @@ fn parse_expected(
108108
last_nonfollow_error: Option<usize>,
109109
line_num: usize,
110110
line: &str,
111-
cfg: Option<&str>,
111+
test_revision: Option<&str>,
112112
) -> Option<(WhichLine, Error)> {
113113
// Matches comments like:
114114
// //~
115115
// //~|
116116
// //~^
117117
// //~^^^^^
118-
// //[cfg1]~
119-
// //[cfg1,cfg2]~^^
118+
// //[rev1]~
119+
// //[rev1,rev2]~^^
120120
static RE: Lazy<Regex> =
121-
Lazy::new(|| Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap());
121+
Lazy::new(|| Regex::new(r"//(?:\[(?P<revs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap());
122122

123123
let captures = RE.captures(line)?;
124124

125-
match (cfg, captures.name("cfgs")) {
126-
// Only error messages that contain our `cfg` between the square brackets apply to us.
127-
(Some(cfg), Some(filter)) if !filter.as_str().split(',').any(|s| s == cfg) => return None,
128-
(Some(_), Some(_)) => {}
125+
match (test_revision, captures.name("revs")) {
126+
// Only error messages that contain our revision between the square brackets apply to us.
127+
(Some(test_revision), Some(revision_filters)) => {
128+
if !revision_filters.as_str().split(',').any(|r| r == test_revision) {
129+
return None;
130+
}
131+
}
129132

130133
(None, Some(_)) => panic!("Only tests with revisions should use `//[X]~`"),
131134

src/tools/compiletest/src/header.rs

+50-37
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,20 @@ impl TestProps {
289289
}
290290
}
291291

292-
pub fn from_aux_file(&self, testfile: &Path, cfg: Option<&str>, config: &Config) -> Self {
292+
pub fn from_aux_file(&self, testfile: &Path, revision: Option<&str>, config: &Config) -> Self {
293293
let mut props = TestProps::new();
294294

295295
// copy over select properties to the aux build:
296296
props.incremental_dir = self.incremental_dir.clone();
297297
props.ignore_pass = true;
298-
props.load_from(testfile, cfg, config);
298+
props.load_from(testfile, revision, config);
299299

300300
props
301301
}
302302

303-
pub fn from_file(testfile: &Path, cfg: Option<&str>, config: &Config) -> Self {
303+
pub fn from_file(testfile: &Path, revision: Option<&str>, config: &Config) -> Self {
304304
let mut props = TestProps::new();
305-
props.load_from(testfile, cfg, config);
305+
props.load_from(testfile, revision, config);
306306

307307
match (props.pass_mode, props.fail_mode) {
308308
(None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check),
@@ -315,9 +315,9 @@ impl TestProps {
315315

316316
/// Loads properties from `testfile` into `props`. If a property is
317317
/// tied to a particular revision `foo` (indicated by writing
318-
/// `//[foo]`), then the property is ignored unless `cfg` is
318+
/// `//@[foo]`), then the property is ignored unless `test_revision` is
319319
/// `Some("foo")`.
320-
fn load_from(&mut self, testfile: &Path, cfg: Option<&str>, config: &Config) {
320+
fn load_from(&mut self, testfile: &Path, test_revision: Option<&str>, config: &Config) {
321321
let mut has_edition = false;
322322
if !testfile.is_dir() {
323323
let file = File::open(testfile).unwrap();
@@ -331,7 +331,7 @@ impl TestProps {
331331
testfile,
332332
file,
333333
&mut |HeaderLine { header_revision, directive: ln, .. }| {
334-
if header_revision.is_some() && header_revision != cfg {
334+
if header_revision.is_some() && header_revision != test_revision {
335335
return;
336336
}
337337

@@ -455,7 +455,7 @@ impl TestProps {
455455
&mut self.check_test_line_numbers_match,
456456
);
457457

458-
self.update_pass_mode(ln, cfg, config);
458+
self.update_pass_mode(ln, test_revision, config);
459459
self.update_fail_mode(ln, config);
460460

461461
config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass);
@@ -645,30 +645,27 @@ impl TestProps {
645645
}
646646
}
647647

648-
/// Extract a `(Option<line_config>, directive)` directive from a line if comment is present.
648+
/// Extract an `(Option<line_revision>, directive)` directive from a line if comment is present.
649+
///
650+
/// See [`HeaderLine`] for a diagram.
649651
pub fn line_directive<'line>(
650652
comment: &str,
651-
ln: &'line str,
653+
original_line: &'line str,
652654
) -> Option<(Option<&'line str>, &'line str)> {
653-
let ln = ln.trim_start();
654-
if ln.starts_with(comment) {
655-
let ln = ln[comment.len()..].trim_start();
656-
if ln.starts_with('[') {
657-
// A comment like `//[foo]` is specific to revision `foo`
658-
let Some(close_brace) = ln.find(']') else {
659-
panic!(
660-
"malformed condition directive: expected `{}[foo]`, found `{}`",
661-
comment, ln
662-
);
663-
};
655+
// Ignore lines that don't start with the comment prefix.
656+
let after_comment = original_line.trim_start().strip_prefix(comment)?.trim_start();
657+
658+
if let Some(after_open_bracket) = after_comment.strip_prefix('[') {
659+
// A comment like `//@[foo]` only applies to revision `foo`.
660+
let Some((line_revision, directive)) = after_open_bracket.split_once(']') else {
661+
panic!(
662+
"malformed condition directive: expected `{comment}[foo]`, found `{original_line}`"
663+
)
664+
};
664665

665-
let lncfg = &ln[1..close_brace];
666-
Some((Some(lncfg), ln[(close_brace + 1)..].trim_start()))
667-
} else {
668-
Some((None, ln))
669-
}
666+
Some((Some(line_revision), directive.trim_start()))
670667
} else {
671-
None
668+
Some((None, after_comment))
672669
}
673670
}
674671

@@ -790,16 +787,32 @@ const DIAGNOSTICS_DIRECTIVE_NAMES: &[&str] = &[
790787
"unset-rustc-env",
791788
];
792789

793-
/// Arguments passed to the callback in [`iter_header`].
790+
/// The broken-down contents of a line containing a test header directive,
791+
/// which [`iter_header`] passes to its callback function.
792+
///
793+
/// For example:
794+
///
795+
/// ```text
796+
/// //@ compile-flags: -O
797+
/// ^^^^^^^^^^^^^^^^^ directive
798+
/// ^^^^^^^^^^^^^^^^^^^^^ original_line
799+
///
800+
/// //@ [foo] compile-flags: -O
801+
/// ^^^ header_revision
802+
/// ^^^^^^^^^^^^^^^^^ directive
803+
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ original_line
804+
/// ```
794805
struct HeaderLine<'ln> {
795-
/// Contents of the square brackets preceding this header, if present.
796-
header_revision: Option<&'ln str>,
806+
line_number: usize,
797807
/// Raw line from the test file, including comment prefix and any revision.
798808
original_line: &'ln str,
799-
/// Remainder of the directive line, after the initial comment prefix
800-
/// (`//` or `//@` or `#`) and revision (if any) have been stripped.
809+
/// Some header directives start with a revision name in square brackets
810+
/// (e.g. `[foo]`), and only apply to that revision of the test.
811+
/// If present, this field contains the revision name (e.g. `foo`).
812+
header_revision: Option<&'ln str>,
813+
/// The main part of the header directive, after removing the comment prefix
814+
/// and the optional revision specifier.
801815
directive: &'ln str,
802-
line_number: usize,
803816
}
804817

805818
fn iter_header(
@@ -831,7 +844,7 @@ fn iter_header(
831844
];
832845
// Process the extra implied directives, with a dummy line number of 0.
833846
for directive in extra_directives {
834-
it(HeaderLine { header_revision: None, original_line: "", directive, line_number: 0 });
847+
it(HeaderLine { line_number: 0, original_line: "", header_revision: None, directive });
835848
}
836849
}
837850

@@ -865,7 +878,7 @@ fn iter_header(
865878

866879
// First try to accept `ui_test` style comments
867880
} else if let Some((header_revision, directive)) = line_directive(comment, ln) {
868-
it(HeaderLine { header_revision, original_line, directive, line_number });
881+
it(HeaderLine { line_number, original_line, header_revision, directive });
869882
} else if mode == Mode::Ui && suite == "ui" && !REVISION_MAGIC_COMMENT_RE.is_match(ln) {
870883
let Some((_, rest)) = line_directive("//", ln) else {
871884
continue;
@@ -1158,7 +1171,7 @@ pub fn make_test_description<R: Read>(
11581171
name: test::TestName,
11591172
path: &Path,
11601173
src: R,
1161-
cfg: Option<&str>,
1174+
test_revision: Option<&str>,
11621175
poisoned: &mut bool,
11631176
) -> test::TestDesc {
11641177
let mut ignore = false;
@@ -1174,7 +1187,7 @@ pub fn make_test_description<R: Read>(
11741187
path,
11751188
src,
11761189
&mut |HeaderLine { header_revision, original_line, directive: ln, line_number }| {
1177-
if header_revision.is_some() && header_revision != cfg {
1190+
if header_revision.is_some() && header_revision != test_revision {
11781191
return;
11791192
}
11801193

src/tools/compiletest/src/header/tests.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ fn make_test_description<R: Read>(
1010
name: test::TestName,
1111
path: &Path,
1212
src: R,
13-
cfg: Option<&str>,
13+
revision: Option<&str>,
1414
) -> test::TestDesc {
1515
let cache = HeadersCache::load(config);
1616
let mut poisoned = false;
17-
let test =
18-
crate::header::make_test_description(config, &cache, name, path, src, cfg, &mut poisoned);
17+
let test = crate::header::make_test_description(
18+
config,
19+
&cache,
20+
name,
21+
path,
22+
src,
23+
revision,
24+
&mut poisoned,
25+
);
1926
if poisoned {
2027
panic!("poisoned!");
2128
}

src/tools/compiletest/src/lib.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -745,28 +745,21 @@ fn make_test(
745745
let revisions = if early_props.revisions.is_empty() || config.mode == Mode::Incremental {
746746
vec![None]
747747
} else {
748-
early_props.revisions.iter().map(Some).collect()
748+
early_props.revisions.iter().map(|r| Some(r.as_str())).collect()
749749
};
750750

751751
revisions
752752
.into_iter()
753753
.map(|revision| {
754754
let src_file =
755755
std::fs::File::open(&test_path).expect("open test file to parse ignores");
756-
let cfg = revision.map(|v| &**v);
757756
let test_name = crate::make_test_name(&config, testpaths, revision);
758757
let mut desc = make_test_description(
759-
&config, cache, test_name, &test_path, src_file, cfg, poisoned,
758+
&config, cache, test_name, &test_path, src_file, revision, poisoned,
760759
);
761760
// Ignore tests that already run and are up to date with respect to inputs.
762761
if !config.force_rerun {
763-
desc.ignore |= is_up_to_date(
764-
&config,
765-
testpaths,
766-
&early_props,
767-
revision.map(|s| s.as_str()),
768-
inputs,
769-
);
762+
desc.ignore |= is_up_to_date(&config, testpaths, &early_props, revision, inputs);
770763
}
771764
test::TestDescAndFn {
772765
desc,
@@ -879,7 +872,7 @@ impl Stamp {
879872
fn make_test_name(
880873
config: &Config,
881874
testpaths: &TestPaths,
882-
revision: Option<&String>,
875+
revision: Option<&str>,
883876
) -> test::TestName {
884877
// Print the name of the file, relative to the repository root.
885878
// `src_base` looks like `/path/to/rust/tests/ui`
@@ -907,11 +900,11 @@ fn make_test_name(
907900
fn make_test_closure(
908901
config: Arc<Config>,
909902
testpaths: &TestPaths,
910-
revision: Option<&String>,
903+
revision: Option<&str>,
911904
) -> test::TestFn {
912905
let config = config.clone();
913906
let testpaths = testpaths.clone();
914-
let revision = revision.cloned();
907+
let revision = revision.map(str::to_owned);
915908
test::DynTestFn(Box::new(move || {
916909
runtest::run(config, &testpaths, revision.as_deref());
917910
Ok(())

0 commit comments

Comments
 (0)