Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize flags for doctest cross compilation #137096

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions src/doc/rustdoc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,23 @@ For more, see [the chapter on documentation tests](write-documentation/documenta

See also `--test`.

## `--test-runtool`, `--test-runtool-arg`: program to run tests with; args to pass to it

Using these options looks like this:

```bash
$ rustdoc src/lib.rs --test-runtool runner --test-runtool-arg --do-thing --test-runtool-arg --do-other-thing
```

These options can be used to run the doctest under a program, and also pass arguments to
that program. For example, if you want to run your doctests under valgrind you might run

```bash
$ rustdoc src/lib.rs --test-runtool valgrind
```

Another use case would be to run a test inside an emulator, or through a Virtual Machine.

## `--target`: generate documentation for the specified target triple

Using this flag looks like this:
Expand Down
54 changes: 0 additions & 54 deletions src/doc/rustdoc/src/unstable-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,60 +612,6 @@ The generated output (formatted) will look like this:
`--output-format html` has no effect, as the default output is HTML. This is
accepted on stable, even though the other options for this flag aren't.

## `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests

* Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245)

Using this flag looks like this:

```bash
$ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores
```

This flag allows you to tag doctests with compiletest style `ignore-foo` filters that prevent
rustdoc from running that test if the target triple string contains foo. For example:

```rust
///```ignore-foo,ignore-bar
///assert!(2 == 2);
///```
struct Foo;
```

This will not be run when the build target is `super-awesome-foo` or `less-bar-awesome`.
If the flag is not enabled, then rustdoc will consume the filter, but do nothing with it, and
the above example will be run for all targets.
If you want to preserve backwards compatibility for older versions of rustdoc, you can use

```rust
///```ignore,ignore-foo
///assert!(2 == 2);
///```
struct Foo;
```

In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will
override `ignore`.

## `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it

* Tracking issue: [#64245](https://github.com/rust-lang/rust/issues/64245)

Using these options looks like this:

```bash
$ rustdoc src/lib.rs -Z unstable-options --runtool runner --runtool-arg --do-thing --runtool-arg --do-other-thing
```

These options can be used to run the doctest under a program, and also pass arguments to
that program. For example, if you want to run your doctests under valgrind you might run

```bash
$ rustdoc src/lib.rs -Z unstable-options --runtool valgrind
```

Another use case would be to run a test inside an emulator, or through a Virtual Machine.

## `--with-examples`: include examples of uses of items as documentation

* Tracking issue: [#88791](https://github.com/rust-lang/rust/issues/88791)
Expand Down
28 changes: 28 additions & 0 deletions src/doc/rustdoc/src/write-documentation/documentation-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,34 @@ should not be merged with the others. So the previous code should use it:
In this case, it means that the line information will not change if you add/remove other
doctests.

### Ignoring targets

Attributes starting with `ignore-` can be used to ignore doctests for specific
targets. For example, `ignore-x86_64` will avoid building doctests when the
target name contains `x86_64`.

```rust
/// ```ignore-x86_64
/// assert!(2 == 2);
/// ```
struct Foo;
```

This doctest will not be built for targets such as `x86_64-unknown-linux-gnu`.

If you want to preserve backwards compatibility for older versions of rustdoc,
you can specify both `ignore` and `ignore-`, such as:

```rust
/// ```ignore,ignore-x86_64
/// assert!(2 == 2);
/// ```
struct Foo;
```

In older versions, this will be ignored on all targets, but starting with
version CURRENT_RUSTC_VERSION, `ignore-x86_64` will override `ignore`.

### Custom CSS classes for code blocks

```rust
Expand Down
23 changes: 8 additions & 15 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,9 @@ pub(crate) struct Options {
/// temporary directory if not set.
pub(crate) persist_doctests: Option<PathBuf>,
/// Runtool to run doctests with
pub(crate) runtool: Option<String>,
pub(crate) test_runtool: Option<String>,
/// Arguments to pass to the runtool
pub(crate) runtool_args: Vec<String>,
/// Whether to allow ignoring doctests on a per-target basis
/// For example, using ignore-foo to ignore running the doctest on any target that
/// contains "foo" as a substring
pub(crate) enable_per_target_ignores: bool,
pub(crate) test_runtool_args: Vec<String>,
/// Do not run doctests, compile them if should_test is active.
pub(crate) no_run: bool,
/// What sources are being mapped.
Expand Down Expand Up @@ -212,9 +208,8 @@ impl fmt::Debug for Options {
.field("persist_doctests", &self.persist_doctests)
.field("show_coverage", &self.show_coverage)
.field("crate_version", &self.crate_version)
.field("runtool", &self.runtool)
.field("runtool_args", &self.runtool_args)
.field("enable-per-target-ignores", &self.enable_per_target_ignores)
.field("test_runtool", &self.test_runtool)
.field("test_runtool_args", &self.test_runtool_args)
.field("run_check", &self.run_check)
.field("no_run", &self.no_run)
.field("test_builder_wrappers", &self.test_builder_wrappers)
Expand Down Expand Up @@ -765,9 +760,8 @@ impl Options {
let unstable_opts_strs = matches.opt_strs("Z");
let lib_strs = matches.opt_strs("L");
let extern_strs = matches.opt_strs("extern");
let runtool = matches.opt_str("runtool");
let runtool_args = matches.opt_strs("runtool-arg");
let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores");
let test_runtool = matches.opt_str("test-runtool");
let test_runtool_args = matches.opt_strs("test-runtool-arg");
let document_private = matches.opt_present("document-private-items");
let document_hidden = matches.opt_present("document-hidden-items");
let run_check = matches.opt_present("check");
Expand Down Expand Up @@ -828,9 +822,8 @@ impl Options {
crate_version,
test_run_directory,
persist_doctests,
runtool,
runtool_args,
enable_per_target_ignores,
test_runtool,
test_runtool_args,
test_builder,
run_check,
no_run,
Expand Down
6 changes: 2 additions & 4 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,9 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
let crate_name = tcx.crate_name(LOCAL_CRATE).to_string();
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
let opts = scrape_test_config(crate_name, crate_attrs, args_path);
let enable_per_target_ignores = options.enable_per_target_ignores;

let hir_collector = HirCollector::new(
ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()),
enable_per_target_ignores,
tcx,
);
let tests = hir_collector.collect_crate();
Expand Down Expand Up @@ -701,10 +699,10 @@ fn run_test(
let mut cmd;

let output_file = make_maybe_absolute_path(output_file);
if let Some(tool) = &rustdoc_options.runtool {
if let Some(tool) = &rustdoc_options.test_runtool {
let tool = make_maybe_absolute_path(tool.into());
cmd = Command::new(tool);
cmd.args(&rustdoc_options.runtool_args);
cmd.args(&rustdoc_options.test_runtool_args);
cmd.arg(&output_file);
} else {
cmd = Command::new(&output_file);
Expand Down
8 changes: 1 addition & 7 deletions src/librustdoc/doctest/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
};
let codes = ErrorCodes::from(options.unstable_features.is_nightly_build());

find_testable_code(
&input_str,
&mut md_collector,
codes,
options.enable_per_target_ignores,
None,
);
find_testable_code(&input_str, &mut md_collector, codes, None);

let mut collector = CreateRunnableDocTests::new(options.clone(), opts);
md_collector.tests.into_iter().for_each(|t| collector.add_test(t));
Expand Down
6 changes: 2 additions & 4 deletions src/librustdoc/doctest/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,18 @@ impl DocTestVisitor for RustCollector {
pub(super) struct HirCollector<'tcx> {
codes: ErrorCodes,
tcx: TyCtxt<'tcx>,
enable_per_target_ignores: bool,
collector: RustCollector,
}

impl<'tcx> HirCollector<'tcx> {
pub fn new(codes: ErrorCodes, enable_per_target_ignores: bool, tcx: TyCtxt<'tcx>) -> Self {
pub fn new(codes: ErrorCodes, tcx: TyCtxt<'tcx>) -> Self {
let collector = RustCollector {
source_map: tcx.sess.psess.clone_source_map(),
cur_path: vec![],
position: DUMMY_SP,
tests: vec![],
};
Self { codes, enable_per_target_ignores, tcx, collector }
Self { codes, tcx, collector }
}

pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> {
Expand Down Expand Up @@ -131,7 +130,6 @@ impl HirCollector<'_> {
&doc,
&mut self.collector,
self.codes,
self.enable_per_target_ignores,
Some(&crate::html::markdown::ExtraInfo::new(self.tcx, def_id, span)),
);
}
Expand Down
30 changes: 8 additions & 22 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
match kind {
CodeBlockKind::Fenced(ref lang) => {
let parse_result =
LangString::parse_without_check(lang, self.check_error_codes, false);
LangString::parse_without_check(lang, self.check_error_codes);
if !parse_result.rust {
let added_classes = parse_result.added_classes;
let lang_string = if let Some(lang) = parse_result.unknown.first() {
Expand Down Expand Up @@ -707,17 +707,15 @@ pub(crate) fn find_testable_code<T: doctest::DocTestVisitor>(
doc: &str,
tests: &mut T,
error_codes: ErrorCodes,
enable_per_target_ignores: bool,
extra_info: Option<&ExtraInfo<'_>>,
) {
find_codes(doc, tests, error_codes, enable_per_target_ignores, extra_info, false)
find_codes(doc, tests, error_codes, extra_info, false)
}

pub(crate) fn find_codes<T: doctest::DocTestVisitor>(
doc: &str,
tests: &mut T,
error_codes: ErrorCodes,
enable_per_target_ignores: bool,
extra_info: Option<&ExtraInfo<'_>>,
include_non_rust: bool,
) {
Expand All @@ -733,12 +731,7 @@ pub(crate) fn find_codes<T: doctest::DocTestVisitor>(
if lang.is_empty() {
Default::default()
} else {
LangString::parse(
lang,
error_codes,
enable_per_target_ignores,
extra_info,
)
LangString::parse(lang, error_codes, extra_info)
}
}
CodeBlockKind::Indented => Default::default(),
Expand Down Expand Up @@ -1162,18 +1155,13 @@ impl Default for LangString {
}

impl LangString {
fn parse_without_check(
string: &str,
allow_error_code_check: ErrorCodes,
enable_per_target_ignores: bool,
) -> Self {
Self::parse(string, allow_error_code_check, enable_per_target_ignores, None)
fn parse_without_check(string: &str, allow_error_code_check: ErrorCodes) -> Self {
Self::parse(string, allow_error_code_check, None)
}

fn parse(
string: &str,
allow_error_code_check: ErrorCodes,
enable_per_target_ignores: bool,
extra: Option<&ExtraInfo<'_>>,
) -> Self {
let allow_error_code_check = allow_error_code_check.as_bool();
Expand Down Expand Up @@ -1201,10 +1189,8 @@ impl LangString {
seen_rust_tags = !seen_other_tags;
}
LangStringToken::LangToken(x) if x.starts_with("ignore-") => {
if enable_per_target_ignores {
ignores.push(x.trim_start_matches("ignore-").to_owned());
seen_rust_tags = !seen_other_tags;
}
ignores.push(x.trim_start_matches("ignore-").to_owned());
seen_rust_tags = !seen_other_tags;
}
LangStringToken::LangToken("rust") => {
data.rust = true;
Expand Down Expand Up @@ -1906,7 +1892,7 @@ pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<Rust
let lang_string = if syntax.is_empty() {
Default::default()
} else {
LangString::parse(syntax, ErrorCodes::Yes, false, Some(extra_info))
LangString::parse(syntax, ErrorCodes::Yes, Some(extra_info))
};
if !lang_string.rust {
continue;
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/markdown/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn test_unique_id() {
fn test_lang_string_parse() {
fn t(lg: LangString) {
let s = &lg.original;
assert_eq!(LangString::parse(s, ErrorCodes::Yes, true, None), lg)
assert_eq!(LangString::parse(s, ErrorCodes::Yes, None), lg)
}

t(Default::default());
Expand Down Expand Up @@ -479,7 +479,7 @@ fn test_markdown_html_escape() {
fn test_find_testable_code_line() {
fn t(input: &str, expect: &[usize]) {
let mut lines = Vec::<usize>::new();
find_testable_code(input, &mut lines, ErrorCodes::No, false, None);
find_testable_code(input, &mut lines, ErrorCodes::No, None);
assert_eq!(lines, expect);
}

Expand Down
16 changes: 4 additions & 12 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,26 +508,18 @@ fn opts() -> Vec<RustcOptGroup> {
"",
),
opt(
Unstable,
FlagMulti,
"",
"enable-per-target-ignores",
"parse ignore-foo for ignoring doctests on a per-target basis",
"",
),
opt(
Unstable,
Stable,
Opt,
"",
"runtool",
"test-runtool",
"",
"The tool to run tests with when building for a different target than host",
),
opt(
Unstable,
Stable,
Multi,
"",
"runtool-arg",
"test-runtool-arg",
"",
"One (of possibly many) arguments to pass to the runtool",
),
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/passes/calculate_doc_coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> {
let has_docs = !i.attrs.doc_strings.is_empty();
let mut tests = Tests { found_tests: 0 };

find_testable_code(&i.doc_value(), &mut tests, ErrorCodes::No, false, None);
find_testable_code(&i.doc_value(), &mut tests, ErrorCodes::No, None);

let has_doc_example = tests.found_tests != 0;
let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/passes/check_doc_test_visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub(crate) fn look_for_tests(cx: &DocContext<'_>, dox: &str, item: &Item) {

let mut tests = Tests { found_tests: 0 };

find_testable_code(dox, &mut tests, ErrorCodes::No, false, None);
find_testable_code(dox, &mut tests, ErrorCodes::No, None);

if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples() {
if should_have_doc_example(cx, item) {
Expand Down
Loading
Loading