Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/tools/compiletest/src/command-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"check-test-line-numbers-match",
"compare-output-lines-by-subset",
"compile-flags",
"doc-flags",
"dont-check-compiler-stderr",
"dont-check-compiler-stdout",
"dont-check-failure-status",
Expand Down Expand Up @@ -225,6 +226,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"should-ice",
"stderr-per-bitwidth",
"test-mir-pass",
"unique-doc-out-dir",
"unset-exec-env",
"unset-rustc-env",
// Used by the tidy check `unknown_revision`.
Expand Down
13 changes: 13 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub struct TestProps {
pub compile_flags: Vec<String>,
// Extra flags to pass when the compiled code is run (such as --bench)
pub run_flags: Vec<String>,
/// Extra flags to pass to rustdoc but not the compiler.
pub doc_flags: Vec<String>,
// If present, the name of a file that this test should match when
// pretty-printed
pub pp_exact: Option<PathBuf>,
Expand Down Expand Up @@ -122,6 +124,9 @@ pub struct TestProps {
pub unset_exec_env: Vec<String>,
// Build documentation for all specified aux-builds as well
pub build_aux_docs: bool,
/// Build the documentation for each crate in a unique output directory.
/// Uses <root output directory>/docs/<test name>/doc
pub unique_doc_out_dir: bool,
// Flag to force a crate to be built with the host architecture
pub force_host: bool,
// Check stdout for error-pattern output as well as stderr
Expand Down Expand Up @@ -220,8 +225,10 @@ mod directives {
pub const REGEX_ERROR_PATTERN: &'static str = "regex-error-pattern";
pub const COMPILE_FLAGS: &'static str = "compile-flags";
pub const RUN_FLAGS: &'static str = "run-flags";
pub const DOC_FLAGS: &'static str = "doc-flags";
pub const SHOULD_ICE: &'static str = "should-ice";
pub const BUILD_AUX_DOCS: &'static str = "build-aux-docs";
pub const UNIQUE_DOC_OUT_DIR: &'static str = "unique-doc-out-dir";
pub const FORCE_HOST: &'static str = "force-host";
pub const CHECK_STDOUT: &'static str = "check-stdout";
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
Expand Down Expand Up @@ -267,6 +274,7 @@ impl TestProps {
regex_error_patterns: vec![],
compile_flags: vec![],
run_flags: vec![],
doc_flags: vec![],
pp_exact: None,
aux_builds: vec![],
aux_bins: vec![],
Expand All @@ -281,6 +289,7 @@ impl TestProps {
exec_env: vec![],
unset_exec_env: vec![],
build_aux_docs: false,
unique_doc_out_dir: false,
force_host: false,
check_stdout: false,
check_run_results: false,
Expand Down Expand Up @@ -377,6 +386,8 @@ impl TestProps {
|r| r,
);

config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r);

fn split_flags(flags: &str) -> Vec<String> {
// Individual flags can be single-quoted to preserve spaces; see
// <https://github.com/rust-lang/rust/pull/115948/commits/957c5db6>.
Expand Down Expand Up @@ -414,6 +425,8 @@ impl TestProps {

config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
config.set_name_directive(ln, BUILD_AUX_DOCS, &mut self.build_aux_docs);
config.set_name_directive(ln, UNIQUE_DOC_OUT_DIR, &mut self.unique_doc_out_dir);

config.set_name_directive(ln, FORCE_HOST, &mut self.force_host);
config.set_name_directive(ln, CHECK_STDOUT, &mut self.check_stdout);
config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut self.check_run_results);
Expand Down
88 changes: 55 additions & 33 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// ignore-tidy-filelength

use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::ffi::{OsStr, OsString};
use std::fs::{self, create_dir_all, File, OpenOptions};
Expand Down Expand Up @@ -723,7 +724,7 @@ impl<'test> TestCx<'test> {
self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
rustc.args(&self.props.compile_flags);

self.compose_and_run_compiler(rustc, Some(src))
self.compose_and_run_compiler(rustc, Some(src), self.testpaths)
}

fn run_debuginfo_test(&self) {
Expand Down Expand Up @@ -1579,13 +1580,15 @@ impl<'test> TestCx<'test> {
passes,
);

self.compose_and_run_compiler(rustc, None)
self.compose_and_run_compiler(rustc, None, self.testpaths)
}

fn document(&self, out_dir: &Path) -> ProcRes {
/// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run.
/// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths.
fn document(&self, root_out_dir: &Path, root_testpaths: &TestPaths) -> ProcRes {
if self.props.build_aux_docs {
for rel_ab in &self.props.aux_builds {
let aux_testpaths = self.compute_aux_test_paths(&self.testpaths, rel_ab);
let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab);
let aux_props =
self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
let aux_cx = TestCx {
Expand All @@ -1596,7 +1599,9 @@ impl<'test> TestCx<'test> {
};
// Create the directory for the stdout/stderr files.
create_dir_all(aux_cx.output_base_dir()).unwrap();
let auxres = aux_cx.document(out_dir);
// use root_testpaths here, because aux-builds should have the
// same --out-dir and auxiliary directory.
let auxres = aux_cx.document(&root_out_dir, root_testpaths);
if !auxres.status.success() {
return auxres;
}
Expand All @@ -1606,21 +1611,40 @@ impl<'test> TestCx<'test> {
let aux_dir = self.aux_output_dir_name();

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

// actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire
// test
let out_dir: Cow<'_, Path> = if self.props.unique_doc_out_dir {
let file_name = self.testpaths.file.file_stem().expect("file name should not be empty");
let out_dir = PathBuf::from_iter([
root_out_dir,
Path::new("docs"),
Path::new(file_name),
Path::new("doc"),
]);
create_dir_all(&out_dir).unwrap();
Cow::Owned(out_dir)
} else {
Cow::Borrowed(root_out_dir)
};

let mut rustdoc = Command::new(rustdoc_path);
let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision());
rustdoc.current_dir(current_dir);
rustdoc
.arg("-L")
.arg(self.config.run_lib_path.to_str().unwrap())
.arg("-L")
.arg(aux_dir)
.arg("-o")
.arg(out_dir)
.arg(out_dir.as_ref())
.arg("--deny")
.arg("warnings")
.arg(&self.testpaths.file)
.arg("-A")
.arg("internal_features")
.args(&self.props.compile_flags);
.args(&self.props.compile_flags)
.args(&self.props.doc_flags);

if self.config.mode == RustdocJson {
rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options");
Expand All @@ -1630,7 +1654,7 @@ impl<'test> TestCx<'test> {
rustdoc.arg(format!("-Clinker={}", linker));
}

self.compose_and_run_compiler(rustdoc, None)
self.compose_and_run_compiler(rustdoc, None, root_testpaths)
}

fn exec_compiled_test(&self) -> ProcRes {
Expand Down Expand Up @@ -1828,9 +1852,16 @@ impl<'test> TestCx<'test> {
}
}

fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
/// `root_testpaths` refers to the path of the original test.
/// the auxiliary and the test with an aux-build have the same `root_testpaths`.
fn compose_and_run_compiler(
&self,
mut rustc: Command,
input: Option<String>,
root_testpaths: &TestPaths,
) -> ProcRes {
let aux_dir = self.aux_output_dir();
self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc);
self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc);

rustc.envs(self.props.rustc_env.clone());
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
Expand Down Expand Up @@ -2545,7 +2576,7 @@ impl<'test> TestCx<'test> {
Vec::new(),
);

let proc_res = self.compose_and_run_compiler(rustc, None);
let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
let output_path = self.get_filecheck_file("ll");
(proc_res, output_path)
}
Expand Down Expand Up @@ -2581,7 +2612,7 @@ impl<'test> TestCx<'test> {
Vec::new(),
);

let proc_res = self.compose_and_run_compiler(rustc, None);
let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
let output_path = self.get_filecheck_file("s");
(proc_res, output_path)
}
Expand Down Expand Up @@ -2664,7 +2695,7 @@ impl<'test> TestCx<'test> {
let out_dir = self.output_base_dir();
remove_and_create_dir_all(&out_dir);

let proc_res = self.document(&out_dir);
let proc_res = self.document(&out_dir, &self.testpaths);
if !proc_res.status.success() {
self.fatal_proc_rec("rustdoc failed!", &proc_res);
}
Expand Down Expand Up @@ -2723,7 +2754,7 @@ impl<'test> TestCx<'test> {
let aux_dir = new_rustdoc.aux_output_dir();
new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc);

let proc_res = new_rustdoc.document(&compare_dir);
let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths);
if !proc_res.status.success() {
eprintln!("failed to run nightly rustdoc");
return;
Expand Down Expand Up @@ -2846,7 +2877,7 @@ impl<'test> TestCx<'test> {
let out_dir = self.output_base_dir();
remove_and_create_dir_all(&out_dir);

let proc_res = self.document(&out_dir);
let proc_res = self.document(&out_dir, &self.testpaths);
if !proc_res.status.success() {
self.fatal_proc_rec("rustdoc failed!", &proc_res);
}
Expand Down Expand Up @@ -2922,24 +2953,15 @@ impl<'test> TestCx<'test> {
fn check_rustdoc_test_option(&self, res: ProcRes) {
let mut other_files = Vec::new();
let mut files: HashMap<String, Vec<usize>> = HashMap::new();
let cwd = env::current_dir().unwrap();
files.insert(
self.testpaths
.file
.strip_prefix(&cwd)
.unwrap_or(&self.testpaths.file)
.to_str()
.unwrap()
.replace('\\', "/"),
self.get_lines(&self.testpaths.file, Some(&mut other_files)),
);
let normalized = fs::canonicalize(&self.testpaths.file).expect("failed to canonicalize");
let normalized = normalized.to_str().unwrap().replace('\\', "/");
files.insert(normalized, self.get_lines(&self.testpaths.file, Some(&mut other_files)));
for other_file in other_files {
let mut path = self.testpaths.file.clone();
path.set_file_name(&format!("{}.rs", other_file));
files.insert(
path.strip_prefix(&cwd).unwrap_or(&path).to_str().unwrap().replace('\\', "/"),
self.get_lines(&path, None),
);
let path = fs::canonicalize(path).expect("failed to canonicalize");
let normalized = path.to_str().unwrap().replace('\\', "/");
files.insert(normalized, self.get_lines(&path, None));
}

let mut tested = 0;
Expand Down Expand Up @@ -3778,7 +3800,7 @@ impl<'test> TestCx<'test> {
if let Some(nodejs) = &self.config.nodejs {
let out_dir = self.output_base_dir();

self.document(&out_dir);
self.document(&out_dir, &self.testpaths);

let root = self.config.find_rust_src_root().unwrap();
let file_stem =
Expand Down Expand Up @@ -4094,7 +4116,7 @@ impl<'test> TestCx<'test> {
rustc.arg(crate_name);
}

let res = self.compose_and_run_compiler(rustc, None);
let res = self.compose_and_run_compiler(rustc, None, self.testpaths);
if !res.status.success() {
self.fatal_proc_rec("failed to compile fixed code", &res);
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<'test> TestCx<'test> {

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

let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None);
let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths);
if !proc_res.status.success() {
self.fatal_proc_rec("rustdoc --test failed!", &proc_res)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//@ build-aux-docs
pub struct Quebec;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//@ aux-build:q.rs
//@ build-aux-docs
extern crate q;
pub trait Tango {}
16 changes: 16 additions & 0 deletions tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ aux-build:t.rs
//@ build-aux-docs
//@ has q/struct.Quebec.html
//@ has s/struct.Sierra.html
//@ has t/trait.Tango.html
//@ hasraw s/struct.Sierra.html 'Tango'
//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html'
//@ hasraw search-index.js 'Tango'
//@ hasraw search-index.js 'Sierra'
//@ hasraw search-index.js 'Quebec'

// We document multiple crates into the same output directory, which
// merges the cross-crate information. Everything is available.
extern crate t;
pub struct Sierra;
impl t::Tango for Sierra {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//@ build-aux-docs
//@ doc-flags:--enable-index-page
//@ doc-flags:-Zunstable-options

pub struct Quebec;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ aux-build:q.rs
//@ build-aux-docs
//@ doc-flags:--enable-index-page
//@ doc-flags:-Zunstable-options

extern crate q;
pub trait Tango {}
24 changes: 24 additions & 0 deletions tests/rustdoc/cross-crate-info/cargo-transitive/s.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ aux-build:t.rs
//@ build-aux-docs
//@ doc-flags:--enable-index-page
//@ doc-flags:-Zunstable-options

//@ has index.html
//@ has index.html '//h1' 'List of all crates'
//@ has index.html '//ul[@class="all-items"]//a[@href="q/index.html"]' 'q'
//@ has index.html '//ul[@class="all-items"]//a[@href="s/index.html"]' 's'
//@ has index.html '//ul[@class="all-items"]//a[@href="t/index.html"]' 't'
//@ has q/struct.Quebec.html
//@ has s/struct.Sierra.html
//@ has t/trait.Tango.html
//@ hasraw s/struct.Sierra.html 'Tango'
//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html'
//@ hasraw search-index.js 'Tango'
//@ hasraw search-index.js 'Sierra'
//@ hasraw search-index.js 'Quebec'

// We document multiple crates into the same output directory, which
// merges the cross-crate information. Everything is available.
extern crate t;
pub struct Sierra;
impl t::Tango for Sierra {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//@ build-aux-docs
pub trait Foxtrot {}
14 changes: 14 additions & 0 deletions tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ aux-build:f.rs
//@ build-aux-docs
//@ has e/enum.Echo.html
//@ has f/trait.Foxtrot.html
//@ hasraw e/enum.Echo.html 'Foxtrot'
//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html'
//@ hasraw search-index.js 'Foxtrot'
//@ hasraw search-index.js 'Echo'

// document two crates in the same way that cargo does. do not provide
// --enable-index-page
extern crate f;
pub enum Echo {}
impl f::Foxtrot for Echo {}
5 changes: 5 additions & 0 deletions tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//@ build-aux-docs
//@ doc-flags:--enable-index-page
//@ doc-flags:-Zunstable-options

pub trait Foxtrot {}
Loading