Skip to content

Commit 0675c97

Browse files
committed
compiletest/codegen-llvm: automatically add needs-target-std if needed
When running the codegen-llvm test suite, the "needs-target-std" directive is automatically added if and only if the "#![no_std]" line is not seen and the "needs-target-std" directive was not already seen. This is a best-effort utility to make running the codegen-llvm test suite for targets that do not support std slightly easier.
1 parent f280e76 commit 0675c97

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed

src/tools/compiletest/src/directives.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ impl TestProps {
358358
fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config: &Config) {
359359
if !testfile.is_dir() {
360360
let file_contents = fs::read_to_string(testfile).unwrap();
361-
let file_directives = FileDirectives::from_file_contents(testfile, &file_contents);
361+
let file_directives =
362+
FileDirectives::from_file_contents(config.suite, testfile, &file_contents);
362363

363364
iter_directives(
364365
config.mode,

src/tools/compiletest/src/directives/file.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,42 @@ pub(crate) struct FileDirectives<'a> {
99
}
1010

1111
impl<'a> FileDirectives<'a> {
12-
pub(crate) fn from_file_contents(path: &'a Utf8Path, file_contents: &'a str) -> Self {
12+
/// Create a new [`FileDirectives`] by iterating through the lines of `file_contents`.
13+
///
14+
/// # Note
15+
///
16+
/// When the `suite` argument matches [`crate::common::TestSuite::CodegenLlvm`] a synthetic
17+
/// `needs-target-std` directive is inserted if needed - that is, if the file does not contain a
18+
/// `#![no_std]` annotation.
19+
///
20+
/// The objective of this addition is that of making it at least a bit easier to run
21+
/// the codegen-llvm test suite for targets that do not have a stdlib, without forcing test
22+
/// writers to remember yet another directive.
23+
pub(crate) fn from_file_contents(
24+
suite: crate::common::TestSuite,
25+
path: &'a Utf8Path,
26+
file_contents: &'a str,
27+
) -> Self {
1328
let mut lines = vec![];
29+
let mut generate_needs_std_stub = true;
1430

1531
for (line_number, ln) in LineNumber::enumerate().zip(file_contents.lines()) {
1632
let ln = ln.trim();
1733

1834
if let Some(directive_line) = line_directive(path, line_number, ln) {
35+
if directive_line.name == "needs-target-std" {
36+
generate_needs_std_stub = false;
37+
}
1938
lines.push(directive_line);
2039
}
40+
41+
if ln == "#![no_std]" {
42+
generate_needs_std_stub = false;
43+
}
44+
}
45+
46+
if generate_needs_std_stub && matches!(suite, crate::common::TestSuite::CodegenLlvm) {
47+
lines.push(crate::directives::line::generate_needs_std(path))
2148
}
2249

2350
Self { path, lines }

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ pub(crate) fn line_directive<'a>(
4141
Some(DirectiveLine { file_path, line_number, revision, raw_directive, name })
4242
}
4343

44+
/// Generate a synthetic [`DirectiveLine`] to add the "needs-target-std" directive to a specific
45+
/// test. See [`crate::FileDirectives::from_file_contents`] for an explanation why this is needed.
46+
#[inline]
47+
pub(crate) fn generate_needs_std<'a>(file_path: &'a Utf8Path) -> DirectiveLine<'a> {
48+
DirectiveLine {
49+
file_path,
50+
line_number: LineNumber::ZERO,
51+
revision: None,
52+
raw_directive: "needs-target-std",
53+
name: "needs-target-std",
54+
}
55+
}
56+
4457
/// The (partly) broken-down contents of a line containing a test directive,
4558
/// which `iter_directives` passes to its callback function.
4659
///

src/tools/compiletest/src/directives/tests.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn make_test_description(
4949
) -> CollectedTestDesc {
5050
let cache = DirectivesCache::load(config);
5151
let mut poisoned = false;
52-
let file_directives = FileDirectives::from_file_contents(path, file_contents);
52+
let file_directives = FileDirectives::from_file_contents(config.suite, path, file_contents);
5353

5454
let mut aux_props = AuxProps::default();
5555
let test = crate::directives::make_test_description(
@@ -268,7 +268,8 @@ fn cfg() -> ConfigBuilder {
268268
}
269269

270270
fn parse_early_props(config: &Config, contents: &str) -> EarlyProps {
271-
let file_directives = FileDirectives::from_file_contents(Utf8Path::new("a.rs"), contents);
271+
let file_directives =
272+
FileDirectives::from_file_contents(config.suite, Utf8Path::new("a.rs"), contents);
272273
EarlyProps::from_file_directives(config, &file_directives)
273274
}
274275

@@ -842,7 +843,12 @@ fn threads_support() {
842843
}
843844

844845
fn run_path(poisoned: &mut bool, path: &Utf8Path, file_contents: &str) {
845-
let file_directives = FileDirectives::from_file_contents(path, file_contents);
846+
let file_directives = FileDirectives::from_file_contents(
847+
// Arbitrary suite to prevent from_file_contents to add synthetic directives.
848+
crate::common::TestSuite::Coverage,
849+
path,
850+
file_contents,
851+
);
846852
let result = directives::do_early_directives_check(TestMode::Ui, &file_directives);
847853
if result.is_err() {
848854
*poisoned = true;

src/tools/compiletest/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
855855
// Scan the test file to discover its revisions, if any.
856856
let file_contents =
857857
fs::read_to_string(&test_path).expect("reading test file for directives should succeed");
858-
let file_directives = FileDirectives::from_file_contents(&test_path, &file_contents);
858+
let file_directives =
859+
FileDirectives::from_file_contents(cx.config.suite, &test_path, &file_contents);
859860

860861
if let Err(message) = directives::do_early_directives_check(cx.config.mode, &file_directives) {
861862
// FIXME(Zalathar): Overhaul compiletest error handling so that we

0 commit comments

Comments
 (0)