Skip to content

Commit 2395a76

Browse files
committed
squash
1 parent 6106b05 commit 2395a76

File tree

31 files changed

+358
-34
lines changed

31 files changed

+358
-34
lines changed

src/tools/compiletest/src/command-list.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
99
"aux-codegen-backend",
1010
"aux-crate",
1111
"build-aux-docs",
12+
"unique-doc-out-dir",
1213
"build-fail",
1314
"build-pass",
1415
"check-fail",
@@ -18,6 +19,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
1819
"check-test-line-numbers-match",
1920
"compare-output-lines-by-subset",
2021
"compile-flags",
22+
"doc-flags",
2123
"dont-check-compiler-stderr",
2224
"dont-check-compiler-stdout",
2325
"dont-check-failure-status",

src/tools/compiletest/src/header.rs

+13
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ pub struct TestProps {
9696
pub compile_flags: Vec<String>,
9797
// Extra flags to pass when the compiled code is run (such as --bench)
9898
pub run_flags: Vec<String>,
99+
/// Extra flags to pass to rustdoc but not the compiler.
100+
pub doc_flags: Vec<String>,
99101
// If present, the name of a file that this test should match when
100102
// pretty-printed
101103
pub pp_exact: Option<PathBuf>,
@@ -123,6 +125,9 @@ pub struct TestProps {
123125
pub unset_exec_env: Vec<String>,
124126
// Build documentation for all specified aux-builds as well
125127
pub build_aux_docs: bool,
128+
/// Build the documentation for each crate in a unique output directory.
129+
/// Uses <root output directory>/docs/<test name>/doc
130+
pub unique_doc_out_dir: bool,
126131
// Flag to force a crate to be built with the host architecture
127132
pub force_host: bool,
128133
// Check stdout for error-pattern output as well as stderr
@@ -221,8 +226,10 @@ mod directives {
221226
pub const REGEX_ERROR_PATTERN: &'static str = "regex-error-pattern";
222227
pub const COMPILE_FLAGS: &'static str = "compile-flags";
223228
pub const RUN_FLAGS: &'static str = "run-flags";
229+
pub const DOC_FLAGS: &'static str = "doc-flags";
224230
pub const SHOULD_ICE: &'static str = "should-ice";
225231
pub const BUILD_AUX_DOCS: &'static str = "build-aux-docs";
232+
pub const UNIQUE_DOC_OUT_DIR: &'static str = "unique-doc-out-dir";
226233
pub const FORCE_HOST: &'static str = "force-host";
227234
pub const CHECK_STDOUT: &'static str = "check-stdout";
228235
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
@@ -268,6 +275,7 @@ impl TestProps {
268275
regex_error_patterns: vec![],
269276
compile_flags: vec![],
270277
run_flags: vec![],
278+
doc_flags: vec![],
271279
pp_exact: None,
272280
aux_builds: vec![],
273281
aux_bins: vec![],
@@ -282,6 +290,7 @@ impl TestProps {
282290
exec_env: vec![],
283291
unset_exec_env: vec![],
284292
build_aux_docs: false,
293+
unique_doc_out_dir: false,
285294
force_host: false,
286295
check_stdout: false,
287296
check_run_results: false,
@@ -378,6 +387,8 @@ impl TestProps {
378387
|r| r,
379388
);
380389

390+
config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r);
391+
381392
fn split_flags(flags: &str) -> Vec<String> {
382393
// Individual flags can be single-quoted to preserve spaces; see
383394
// <https://github.com/rust-lang/rust/pull/115948/commits/957c5db6>.
@@ -415,6 +426,8 @@ impl TestProps {
415426

416427
config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
417428
config.set_name_directive(ln, BUILD_AUX_DOCS, &mut self.build_aux_docs);
429+
config.set_name_directive(ln, UNIQUE_DOC_OUT_DIR, &mut self.unique_doc_out_dir);
430+
418431
config.set_name_directive(ln, FORCE_HOST, &mut self.force_host);
419432
config.set_name_directive(ln, CHECK_STDOUT, &mut self.check_stdout);
420433
config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut self.check_run_results);

src/tools/compiletest/src/runtest.rs

+60-33
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use colored::Colorize;
2121
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
2222
use regex::{Captures, Regex};
2323
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
24+
use std::borrow::Cow;
2425
use std::collections::{HashMap, HashSet};
2526
use std::env;
2627
use std::ffi::{OsStr, OsString};
@@ -731,7 +732,7 @@ impl<'test> TestCx<'test> {
731732
self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
732733
rustc.args(&self.props.compile_flags);
733734

734-
self.compose_and_run_compiler(rustc, Some(src))
735+
self.compose_and_run_compiler(rustc, Some(src), self.testpaths)
735736
}
736737

737738
fn run_debuginfo_test(&self) {
@@ -1587,13 +1588,15 @@ impl<'test> TestCx<'test> {
15871588
passes,
15881589
);
15891590

1590-
self.compose_and_run_compiler(rustc, None)
1591+
self.compose_and_run_compiler(rustc, None, self.testpaths)
15911592
}
15921593

1593-
fn document(&self, out_dir: &Path) -> ProcRes {
1594+
/// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run.
1595+
/// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths.
1596+
fn document(&self, root_out_dir: &Path, root_testpaths: &TestPaths) -> ProcRes {
15941597
if self.props.build_aux_docs {
15951598
for rel_ab in &self.props.aux_builds {
1596-
let aux_testpaths = self.compute_aux_test_paths(&self.testpaths, rel_ab);
1599+
let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab);
15971600
let aux_props =
15981601
self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
15991602
let aux_cx = TestCx {
@@ -1604,7 +1607,7 @@ impl<'test> TestCx<'test> {
16041607
};
16051608
// Create the directory for the stdout/stderr files.
16061609
create_dir_all(aux_cx.output_base_dir()).unwrap();
1607-
let auxres = aux_cx.document(out_dir);
1610+
let auxres = aux_cx.document(&root_out_dir, root_testpaths);
16081611
if !auxres.status.success() {
16091612
return auxres;
16101613
}
@@ -1614,21 +1617,47 @@ impl<'test> TestCx<'test> {
16141617
let aux_dir = self.aux_output_dir_name();
16151618

16161619
let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path not passed");
1617-
let mut rustdoc = Command::new(rustdoc_path);
16181620

1621+
// actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire
1622+
// test
1623+
let out_dir: Cow<'_, Path> = if self.props.unique_doc_out_dir {
1624+
let file_name = self
1625+
.testpaths
1626+
.file
1627+
.file_name()
1628+
.expect("file name should not be empty")
1629+
.to_str()
1630+
.expect("file name utf8")
1631+
.trim_end_matches(".rs");
1632+
let out_dir = PathBuf::from_iter([
1633+
root_out_dir,
1634+
Path::new("docs"),
1635+
Path::new(file_name),
1636+
Path::new("doc"),
1637+
]);
1638+
create_dir_all(&out_dir).unwrap();
1639+
Cow::Owned(out_dir)
1640+
} else {
1641+
Cow::Borrowed(root_out_dir)
1642+
};
1643+
1644+
let mut rustdoc = Command::new(rustdoc_path);
1645+
let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision());
1646+
rustdoc.current_dir(current_dir);
16191647
rustdoc
16201648
.arg("-L")
16211649
.arg(self.config.run_lib_path.to_str().unwrap())
16221650
.arg("-L")
16231651
.arg(aux_dir)
16241652
.arg("-o")
1625-
.arg(out_dir)
1653+
.arg(out_dir.as_ref())
16261654
.arg("--deny")
16271655
.arg("warnings")
16281656
.arg(&self.testpaths.file)
16291657
.arg("-A")
16301658
.arg("internal_features")
1631-
.args(&self.props.compile_flags);
1659+
.args(&self.props.compile_flags)
1660+
.args(&self.props.doc_flags);
16321661

16331662
if self.config.mode == RustdocJson {
16341663
rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options");
@@ -1638,7 +1667,7 @@ impl<'test> TestCx<'test> {
16381667
rustdoc.arg(format!("-Clinker={}", linker));
16391668
}
16401669

1641-
self.compose_and_run_compiler(rustdoc, None)
1670+
self.compose_and_run_compiler(rustdoc, None, root_testpaths)
16421671
}
16431672

16441673
fn exec_compiled_test(&self) -> ProcRes {
@@ -1836,9 +1865,16 @@ impl<'test> TestCx<'test> {
18361865
}
18371866
}
18381867

1839-
fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
1868+
/// `root_testpaths` refers to the path of the original test.
1869+
/// the auxiliary and the test with an aux-build have the same `root_testpaths`.
1870+
fn compose_and_run_compiler(
1871+
&self,
1872+
mut rustc: Command,
1873+
input: Option<String>,
1874+
root_testpaths: &TestPaths,
1875+
) -> ProcRes {
18401876
let aux_dir = self.aux_output_dir();
1841-
self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc);
1877+
self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc);
18421878

18431879
rustc.envs(self.props.rustc_env.clone());
18441880
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
@@ -2553,7 +2589,7 @@ impl<'test> TestCx<'test> {
25532589
Vec::new(),
25542590
);
25552591

2556-
let proc_res = self.compose_and_run_compiler(rustc, None);
2592+
let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
25572593
let output_path = self.get_filecheck_file("ll");
25582594
(proc_res, output_path)
25592595
}
@@ -2589,7 +2625,7 @@ impl<'test> TestCx<'test> {
25892625
Vec::new(),
25902626
);
25912627

2592-
let proc_res = self.compose_and_run_compiler(rustc, None);
2628+
let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
25932629
let output_path = self.get_filecheck_file("s");
25942630
(proc_res, output_path)
25952631
}
@@ -2672,7 +2708,7 @@ impl<'test> TestCx<'test> {
26722708
let out_dir = self.output_base_dir();
26732709
remove_and_create_dir_all(&out_dir);
26742710

2675-
let proc_res = self.document(&out_dir);
2711+
let proc_res = self.document(&out_dir, &self.testpaths);
26762712
if !proc_res.status.success() {
26772713
self.fatal_proc_rec("rustdoc failed!", &proc_res);
26782714
}
@@ -2731,7 +2767,7 @@ impl<'test> TestCx<'test> {
27312767
let aux_dir = new_rustdoc.aux_output_dir();
27322768
new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc);
27332769

2734-
let proc_res = new_rustdoc.document(&compare_dir);
2770+
let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths);
27352771
if !proc_res.status.success() {
27362772
eprintln!("failed to run nightly rustdoc");
27372773
return;
@@ -2854,7 +2890,7 @@ impl<'test> TestCx<'test> {
28542890
let out_dir = self.output_base_dir();
28552891
remove_and_create_dir_all(&out_dir);
28562892

2857-
let proc_res = self.document(&out_dir);
2893+
let proc_res = self.document(&out_dir, &self.testpaths);
28582894
if !proc_res.status.success() {
28592895
self.fatal_proc_rec("rustdoc failed!", &proc_res);
28602896
}
@@ -2930,24 +2966,15 @@ impl<'test> TestCx<'test> {
29302966
fn check_rustdoc_test_option(&self, res: ProcRes) {
29312967
let mut other_files = Vec::new();
29322968
let mut files: HashMap<String, Vec<usize>> = HashMap::new();
2933-
let cwd = env::current_dir().unwrap();
2934-
files.insert(
2935-
self.testpaths
2936-
.file
2937-
.strip_prefix(&cwd)
2938-
.unwrap_or(&self.testpaths.file)
2939-
.to_str()
2940-
.unwrap()
2941-
.replace('\\', "/"),
2942-
self.get_lines(&self.testpaths.file, Some(&mut other_files)),
2943-
);
2969+
let normalized = fs::canonicalize(&self.testpaths.file).expect("failed to canonicalize");
2970+
let normalized = normalized.to_str().unwrap().replace('\\', "/");
2971+
files.insert(normalized, self.get_lines(&self.testpaths.file, Some(&mut other_files)));
29442972
for other_file in other_files {
29452973
let mut path = self.testpaths.file.clone();
29462974
path.set_file_name(&format!("{}.rs", other_file));
2947-
files.insert(
2948-
path.strip_prefix(&cwd).unwrap_or(&path).to_str().unwrap().replace('\\', "/"),
2949-
self.get_lines(&path, None),
2950-
);
2975+
let path = fs::canonicalize(path).expect("failed to canonicalize");
2976+
let normalized = path.to_str().unwrap().replace('\\', "/");
2977+
files.insert(normalized, self.get_lines(&path, None));
29512978
}
29522979

29532980
let mut tested = 0;
@@ -3786,7 +3813,7 @@ impl<'test> TestCx<'test> {
37863813
if let Some(nodejs) = &self.config.nodejs {
37873814
let out_dir = self.output_base_dir();
37883815

3789-
self.document(&out_dir);
3816+
self.document(&out_dir, &self.testpaths);
37903817

37913818
let root = self.config.find_rust_src_root().unwrap();
37923819
let file_stem =
@@ -4102,7 +4129,7 @@ impl<'test> TestCx<'test> {
41024129
rustc.arg(crate_name);
41034130
}
41044131

4105-
let res = self.compose_and_run_compiler(rustc, None);
4132+
let res = self.compose_and_run_compiler(rustc, None, self.testpaths);
41064133
if !res.status.success() {
41074134
self.fatal_proc_rec("failed to compile fixed code", &res);
41084135
}

src/tools/compiletest/src/runtest/coverage.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<'test> TestCx<'test> {
191191

192192
rustdoc_cmd.arg(&self.testpaths.file);
193193

194-
let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None);
194+
let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths);
195195
if !proc_res.status.success() {
196196
self.fatal_proc_rec("rustdoc --test failed!", &proc_res)
197197
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//@ build-aux-docs
2+
3+
4+
pub struct Quebec;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@ aux-build:q.rs
2+
//@ build-aux-docs
3+
4+
5+
extern crate q;
6+
pub trait Tango {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ aux-build:t.rs
2+
//@ build-aux-docs
3+
4+
//@ has t/trait.Tango.html
5+
//@ hasraw search-index.js 'Quebec'
6+
//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html'
7+
//@ hasraw s/struct.Sierra.html 'Tango'
8+
//@ hasraw search-index.js 'Sierra'
9+
//@ hasraw search-index.js 'Tango'
10+
//@ has q/struct.Quebec.html
11+
//@ has s/struct.Sierra.html
12+
13+
// We document multiple crates into the same output directory, which merges the cross-crate information. Everything is available.
14+
15+
extern crate t;
16+
pub struct Sierra;
17+
impl t::Tango for Sierra {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@ build-aux-docs
2+
//@ doc-flags:--enable-index-page
3+
//@ doc-flags:-Zunstable-options
4+
5+
6+
pub struct Quebec;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ aux-build:q.rs
2+
//@ build-aux-docs
3+
//@ doc-flags:--enable-index-page
4+
//@ doc-flags:-Zunstable-options
5+
6+
7+
extern crate q;
8+
pub trait Tango {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ aux-build:t.rs
2+
//@ build-aux-docs
3+
//@ doc-flags:--enable-index-page
4+
//@ doc-flags:-Zunstable-options
5+
6+
//@ has t/trait.Tango.html
7+
//@ hasraw search-index.js 'Quebec'
8+
//@ has index.html '//ul[@class="all-items"]//a[@href="q/index.html"]' 'q'
9+
//@ hasraw s/struct.Sierra.html 'Tango'
10+
//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html'
11+
//@ has index.html '//ul[@class="all-items"]//a[@href="t/index.html"]' 't'
12+
//@ has index.html '//h1' 'List of all crates'
13+
//@ has index.html '//ul[@class="all-items"]//a[@href="s/index.html"]' 's'
14+
//@ hasraw search-index.js 'Sierra'
15+
//@ hasraw search-index.js 'Tango'
16+
//@ has index.html
17+
//@ has q/struct.Quebec.html
18+
//@ has s/struct.Sierra.html
19+
20+
// We document multiple crates into the same output directory, which merges the cross-crate information. Everything is available.
21+
22+
extern crate t;
23+
pub struct Sierra;
24+
impl t::Tango for Sierra {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//@ build-aux-docs
2+
3+
4+
pub trait Foxtrot {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ aux-build:f.rs
2+
//@ build-aux-docs
3+
4+
//@ hasraw search-index.js 'Echo'
5+
//@ hasraw search-index.js 'Foxtrot'
6+
//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html'
7+
//@ has f/trait.Foxtrot.html
8+
//@ has e/enum.Echo.html
9+
//@ hasraw e/enum.Echo.html 'Foxtrot'
10+
11+
// document two crates in the same way that cargo does. do not provide --enable-index-page
12+
13+
extern crate f;
14+
pub enum Echo {}
15+
impl f::Foxtrot for Echo {}

0 commit comments

Comments
 (0)