Auto merge of #79762 - Swatinem:remap-doctest-coverage, r=Swatinem
Remap instrument-coverage line numbers in doctests This uses the `SourceMap::doctest_offset_line` method to re-map line numbers from doctests. Remapping columns is not yet done, and rustdoc still does not output the correct filename when running doctests in a workspace. Part of #79417 although I dont consider that fixed until both filenames and columns are mapped correctly. r? `@richkadel` I might jump on zulip the comming days. Still need to figure out how to properly write tests for this, and deal with other doctest issues in the meantime.
This commit is contained in:
commit
cae1f4ddf2
@ -30,6 +30,7 @@ use rustc_middle::mir::{
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol};
|
||||
|
||||
/// A simple error message wrapper for `coverage::Error`s.
|
||||
@ -311,7 +312,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
|
||||
self.mir_body,
|
||||
counter_kind,
|
||||
self.bcb_leader_bb(bcb),
|
||||
Some(make_code_region(file_name, &self.source_file, span, body_span)),
|
||||
Some(make_code_region(source_map, file_name, &self.source_file, span, body_span)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -489,6 +490,7 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: Co
|
||||
|
||||
/// Convert the Span into its file name, start line and column, and end line and column
|
||||
fn make_code_region(
|
||||
source_map: &SourceMap,
|
||||
file_name: Symbol,
|
||||
source_file: &Lrc<SourceFile>,
|
||||
span: Span,
|
||||
@ -508,6 +510,8 @@ fn make_code_region(
|
||||
} else {
|
||||
source_file.lookup_file_pos(span.hi())
|
||||
};
|
||||
let start_line = source_map.doctest_offset_line(&source_file.name, start_line);
|
||||
let end_line = source_map.doctest_offset_line(&source_file.name, end_line);
|
||||
CodeRegion {
|
||||
file_name,
|
||||
start_line: start_line as u32,
|
||||
|
@ -182,7 +182,7 @@ impl std::fmt::Display for FileName {
|
||||
use FileName::*;
|
||||
match *self {
|
||||
Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()),
|
||||
// FIXME: might be nice to display both compoments of Devirtualized.
|
||||
// FIXME: might be nice to display both components of Devirtualized.
|
||||
// But for now (to backport fix for issue #70924), best to not
|
||||
// perturb diagnostics so its obvious test suite still works.
|
||||
Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => {
|
||||
|
@ -247,9 +247,10 @@ fn run_test(
|
||||
edition: Edition,
|
||||
outdir: DirState,
|
||||
path: PathBuf,
|
||||
test_id: &str,
|
||||
) -> Result<(), TestFailure> {
|
||||
let (test, line_offset, supports_color) =
|
||||
make_test(test, Some(cratename), as_test_harness, opts, edition);
|
||||
make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id));
|
||||
|
||||
let output_file = outdir.path().join("rust_out");
|
||||
|
||||
@ -387,6 +388,7 @@ crate fn make_test(
|
||||
dont_insert_main: bool,
|
||||
opts: &TestOptions,
|
||||
edition: Edition,
|
||||
test_id: Option<&str>,
|
||||
) -> (String, usize, bool) {
|
||||
let (crate_attrs, everything_else, crates) = partition_source(s);
|
||||
let everything_else = everything_else.trim();
|
||||
@ -542,16 +544,41 @@ crate fn make_test(
|
||||
prog.push_str(everything_else);
|
||||
} else {
|
||||
let returns_result = everything_else.trim_end().ends_with("(())");
|
||||
// Give each doctest main function a unique name.
|
||||
// This is for example needed for the tooling around `-Z instrument-coverage`.
|
||||
let inner_fn_name = if let Some(test_id) = test_id {
|
||||
format!("_doctest_main_{}", test_id)
|
||||
} else {
|
||||
"_inner".into()
|
||||
};
|
||||
let inner_attr = if test_id.is_some() { "#[allow(non_snake_case)] " } else { "" };
|
||||
let (main_pre, main_post) = if returns_result {
|
||||
(
|
||||
"fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
|
||||
"}\n_inner().unwrap() }",
|
||||
format!(
|
||||
"fn main() {{ {}fn {}() -> Result<(), impl core::fmt::Debug> {{\n",
|
||||
inner_attr, inner_fn_name
|
||||
),
|
||||
format!("\n}}; {}().unwrap() }}", inner_fn_name),
|
||||
)
|
||||
} else if test_id.is_some() {
|
||||
(
|
||||
format!("fn main() {{ {}fn {}() {{\n", inner_attr, inner_fn_name),
|
||||
format!("\n}}; {}() }}", inner_fn_name),
|
||||
)
|
||||
} else {
|
||||
("fn main() {\n", "\n}")
|
||||
("fn main() {\n".into(), "\n}".into())
|
||||
};
|
||||
prog.extend([main_pre, everything_else, main_post].iter().cloned());
|
||||
// Note on newlines: We insert a line/newline *before*, and *after*
|
||||
// the doctest and adjust the `line_offset` accordingly.
|
||||
// In the case of `-Z instrument-coverage`, this means that the generated
|
||||
// inner `main` function spans from the doctest opening codeblock to the
|
||||
// closing one. For example
|
||||
// /// ``` <- start of the inner main
|
||||
// /// <- code under doctest
|
||||
// /// ``` <- end of the inner main
|
||||
line_offset += 1;
|
||||
|
||||
prog.extend([&main_pre, everything_else, &main_post].iter().cloned());
|
||||
}
|
||||
|
||||
debug!("final doctest:\n{}", prog);
|
||||
@ -749,28 +776,24 @@ impl Tester for Collector {
|
||||
_ => PathBuf::from(r"doctest.rs"),
|
||||
};
|
||||
|
||||
// For example `module/file.rs` would become `module_file_rs`
|
||||
let file = filename
|
||||
.to_string()
|
||||
.chars()
|
||||
.map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
|
||||
.collect::<String>();
|
||||
let test_id = format!(
|
||||
"{file}_{line}_{number}",
|
||||
file = file,
|
||||
line = line,
|
||||
number = {
|
||||
// Increases the current test number, if this file already
|
||||
// exists or it creates a new entry with a test number of 0.
|
||||
self.visited_tests.entry((file.clone(), line)).and_modify(|v| *v += 1).or_insert(0)
|
||||
},
|
||||
);
|
||||
let outdir = if let Some(mut path) = options.persist_doctests.clone() {
|
||||
// For example `module/file.rs` would become `module_file_rs`
|
||||
let folder_name = filename
|
||||
.to_string()
|
||||
.chars()
|
||||
.map(|c| if c == '\\' || c == '/' || c == '.' { '_' } else { c })
|
||||
.collect::<String>();
|
||||
|
||||
path.push(format!(
|
||||
"{krate}_{file}_{line}_{number}",
|
||||
krate = cratename,
|
||||
file = folder_name,
|
||||
line = line,
|
||||
number = {
|
||||
// Increases the current test number, if this file already
|
||||
// exists or it creates a new entry with a test number of 0.
|
||||
self.visited_tests
|
||||
.entry((folder_name.clone(), line))
|
||||
.and_modify(|v| *v += 1)
|
||||
.or_insert(0)
|
||||
},
|
||||
));
|
||||
path.push(&test_id);
|
||||
|
||||
std::fs::create_dir_all(&path)
|
||||
.expect("Couldn't create directory for doctest executables");
|
||||
@ -817,6 +840,7 @@ impl Tester for Collector {
|
||||
edition,
|
||||
outdir,
|
||||
path,
|
||||
&test_id,
|
||||
);
|
||||
|
||||
if let Err(err) = res {
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 3));
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ use std::*;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 3));
|
||||
|
||||
// Adding more will also bump the returned line offset.
|
||||
@ -147,7 +147,7 @@ use asdf::qwop;
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 4));
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ assert_eq!(2+2, 4);";
|
||||
//Ceci n'est pas une `fn main`
|
||||
assert_eq!(2+2, 4);"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ fn make_test_display_warnings() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
|
||||
let input = "extern crate hella_qwop;
|
||||
@ -256,7 +256,7 @@ assert_eq!(asdf::foo, 4);
|
||||
}"
|
||||
.to_string();
|
||||
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 3));
|
||||
}
|
||||
|
||||
@ -274,6 +274,41 @@ test_wrapper! {
|
||||
}"
|
||||
.to_string();
|
||||
|
||||
let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION);
|
||||
let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_test_returns_result() {
|
||||
// creates an inner function and unwraps it
|
||||
let opts = TestOptions::default();
|
||||
let input = "use std::io;
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input)?;
|
||||
Ok::<(), io:Error>(())";
|
||||
let expected = "#![allow(unused)]
|
||||
fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {
|
||||
use std::io;
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input)?;
|
||||
Ok::<(), io:Error>(())
|
||||
}; _inner().unwrap() }"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_test_named_wrapper() {
|
||||
// creates an inner function with a specific name
|
||||
let opts = TestOptions::default();
|
||||
let input = "assert_eq!(2+2, 4);";
|
||||
let expected = "#![allow(unused)]
|
||||
fn main() { #[allow(non_snake_case)] fn _doctest_main__some_unique_name() {
|
||||
assert_eq!(2+2, 4);
|
||||
}; _doctest_main__some_unique_name() }"
|
||||
.to_string();
|
||||
let (output, len, _) =
|
||||
make_test(input, None, false, &opts, DEFAULT_EDITION, Some("_some_unique_name"));
|
||||
assert_eq!((output, len), (expected, 2));
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||
.join("\n");
|
||||
let krate = krate.as_ref().map(|s| &**s);
|
||||
let (test, _, _) =
|
||||
doctest::make_test(&test, krate, false, &Default::default(), edition);
|
||||
doctest::make_test(&test, krate, false, &Default::default(), edition, None);
|
||||
let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" };
|
||||
|
||||
let edition_string = format!("&edition={}", edition);
|
||||
|
@ -98,7 +98,7 @@ endif
|
||||
# Run it in order to generate some profiling data,
|
||||
# with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
|
||||
# output the coverage stats for this run.
|
||||
LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
|
||||
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
|
||||
$(call RUN,$@) || \
|
||||
( \
|
||||
status=$$?; \
|
||||
@ -108,9 +108,16 @@ endif
|
||||
) \
|
||||
)
|
||||
|
||||
# Run it through rustdoc as well to cover doctests
|
||||
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
|
||||
$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
|
||||
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \
|
||||
-L "$(TMPDIR)" -Zinstrument-coverage \
|
||||
-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
|
||||
|
||||
# Postprocess the profiling data so it can be used by the llvm-cov tool
|
||||
"$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
|
||||
"$(TMPDIR)"/$@.profraw \
|
||||
"$(TMPDIR)"/$@-*.profraw \
|
||||
-o "$(TMPDIR)"/$@.profdata
|
||||
|
||||
# Generate a coverage report using `llvm-cov show`.
|
||||
@ -121,8 +128,15 @@ endif
|
||||
--show-line-counts-or-regions \
|
||||
--instr-profile="$(TMPDIR)"/$@.profdata \
|
||||
$(call BIN,"$(TMPDIR)"/$@) \
|
||||
> "$(TMPDIR)"/actual_show_coverage.$@.txt \
|
||||
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt || \
|
||||
$$( \
|
||||
for file in $(TMPDIR)/rustdoc-$@/*/rust_out; \
|
||||
do \
|
||||
[[ -x $$file ]] && printf "%s %s " -object $$file; \
|
||||
done \
|
||||
) \
|
||||
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
|
||||
| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
|
||||
> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
|
||||
( status=$$? ; \
|
||||
>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
|
||||
exit $$status \
|
||||
|
@ -0,0 +1,79 @@
|
||||
../coverage/doctest.rs:
|
||||
1| |//! This test ensures that code from doctests is properly re-mapped.
|
||||
2| |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
|
||||
3| |//!
|
||||
4| |//! Just some random code:
|
||||
5| 1|//! ```
|
||||
6| 1|//! if true {
|
||||
7| |//! // this is executed!
|
||||
8| 1|//! assert_eq!(1, 1);
|
||||
9| |//! } else {
|
||||
10| |//! // this is not!
|
||||
11| |//! assert_eq!(1, 2);
|
||||
12| |//! }
|
||||
13| 1|//! ```
|
||||
14| |//!
|
||||
15| |//! doctest testing external code:
|
||||
16| |//! ```
|
||||
17| 1|//! extern crate doctest_crate;
|
||||
18| 1|//! doctest_crate::fn_run_in_doctests(1);
|
||||
19| 1|//! ```
|
||||
20| |//!
|
||||
21| |//! doctest returning a result:
|
||||
22| 1|//! ```
|
||||
23| 1|//! #[derive(Debug)]
|
||||
24| 1|//! struct SomeError;
|
||||
25| 1|//! let mut res = Err(SomeError);
|
||||
26| 1|//! if res.is_ok() {
|
||||
27| 0|//! res?;
|
||||
28| 1|//! } else {
|
||||
29| 1|//! res = Ok(0);
|
||||
30| 1|//! }
|
||||
31| |//! // need to be explicit because rustdoc cant infer the return type
|
||||
32| 1|//! Ok::<(), SomeError>(())
|
||||
33| 1|//! ```
|
||||
34| |//!
|
||||
35| |//! doctest with custom main:
|
||||
36| |//! ```
|
||||
37| |//! #[derive(Debug)]
|
||||
38| |//! struct SomeError;
|
||||
39| |//!
|
||||
40| |//! extern crate doctest_crate;
|
||||
41| |//!
|
||||
42| 1|//! fn doctest_main() -> Result<(), SomeError> {
|
||||
43| 1|//! doctest_crate::fn_run_in_doctests(2);
|
||||
44| 1|//! Ok(())
|
||||
45| 1|//! }
|
||||
46| |//!
|
||||
47| |//! // this `main` is not shown as covered, as it clashes with all the other
|
||||
48| |//! // `main` functions that were automatically generated for doctests
|
||||
49| |//! fn main() -> Result<(), SomeError> {
|
||||
50| |//! doctest_main()
|
||||
51| |//! }
|
||||
52| |//! ```
|
||||
53| |
|
||||
54| |/// doctest attached to fn testing external code:
|
||||
55| |/// ```
|
||||
56| 1|/// extern crate doctest_crate;
|
||||
57| 1|/// doctest_crate::fn_run_in_doctests(3);
|
||||
58| 1|/// ```
|
||||
59| |///
|
||||
60| 1|fn main() {
|
||||
61| 1| if true {
|
||||
62| 1| assert_eq!(1, 1);
|
||||
63| | } else {
|
||||
64| | assert_eq!(1, 2);
|
||||
65| | }
|
||||
66| 1|}
|
||||
|
||||
../coverage/lib/doctest_crate.rs:
|
||||
1| |/// A function run only from within doctests
|
||||
2| 3|pub fn fn_run_in_doctests(conditional: usize) {
|
||||
3| 3| match conditional {
|
||||
4| 1| 1 => assert_eq!(1, 1), // this is run,
|
||||
5| 1| 2 => assert_eq!(1, 1), // this,
|
||||
6| 1| 3 => assert_eq!(1, 1), // and this too
|
||||
7| 0| _ => assert_eq!(1, 2), // however this is not
|
||||
8| | }
|
||||
9| 3|}
|
||||
|
@ -19,12 +19,12 @@
|
||||
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
19| 2|}
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
------------------
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
|
||||
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
|
||||
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
|
||||
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
|
||||
| 19| 1|}
|
||||
|
12
src/test/run-make-fulldeps/coverage-reports/normalize_paths.py
Executable file
12
src/test/run-make-fulldeps/coverage-reports/normalize_paths.py
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
# Normalize file paths in output
|
||||
for line in sys.stdin:
|
||||
if line.startswith("..") and line.rstrip().endswith(".rs:"):
|
||||
print(line.replace("\\", "/"), end='')
|
||||
else:
|
||||
print(line, end='')
|
@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest/doctest.main.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>doctest.main - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 59"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>fn main() <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> if </span><span><span class="code even" style="--layer: 1" title="61:8-61:12: @0[1]: _1 = const true
|
||||
61:8-61:12: @0[2]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>true<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">@5⦊</span></span></span><span class="code even" style="--layer: 2" title="62:9-62:26: @6[5]: _75 = const main::promoted[3]
|
||||
62:9-62:26: @6[6]: _18 = &(*_75)
|
||||
62:9-62:26: @6[7]: _17 = &(*_18)
|
||||
62:9-62:26: @6[8]: _16 = move _17 as &[&str] (Pointer(Unsize))
|
||||
62:9-62:26: @6[17]: _26 = &(*_8)
|
||||
62:9-62:26: @6[18]: _25 = &_26
|
||||
62:9-62:26: @6[21]: _28 = &(*_9)
|
||||
62:9-62:26: @6[22]: _27 = &_28
|
||||
62:9-62:26: @6[23]: _24 = (move _25, move _27)
|
||||
62:9-62:26: @6[26]: FakeRead(ForMatchedPlace, _24)
|
||||
62:9-62:26: @6[28]: _29 = (_24.0: &&i32)
|
||||
62:9-62:26: @6[30]: _30 = (_24.1: &&i32)
|
||||
62:9-62:26: @6[33]: _32 = &(*_29)
|
||||
62:9-62:26: @6[35]: _33 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
62:9-62:26: @6.Call: _31 = ArgumentV1::new::<&i32>(move _32, move _33) -> [return: bb7, unwind: bb17]
|
||||
62:9-62:26: @7[4]: _35 = &(*_30)
|
||||
62:9-62:26: @7[6]: _36 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
62:9-62:26: @7.Call: _34 = ArgumentV1::new::<&i32>(move _35, move _36) -> [return: bb8, unwind: bb17]
|
||||
62:9-62:26: @8[2]: _23 = [move _31, move _34]
|
||||
62:9-62:26: @8[7]: _22 = &_23
|
||||
62:9-62:26: @8[8]: _21 = &(*_22)
|
||||
62:9-62:26: @8[9]: _20 = move _21 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
62:9-62:26: @8.Call: _15 = Arguments::new_v1(move _16, move _20) -> [return: bb9, unwind: bb17]
|
||||
62:9-62:26: @9.Call: core::panicking::panic_fmt(move _15) -> bb17"><span class="annotation">@4,6,7,8,9⦊</span>assert_eq!(1, 1);<span class="annotation">⦉@4,6,7,8,9</span></span><span><span class="code odd" style="--layer: 1" title="62:9-62:26: @5[0]: _2 = const ()"><span class="annotation">⦉@5</span></span></span><span class="code" style="--layer: 0"></span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> } else {</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> </span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">@11⦊</span></span></span><span class="code even" style="--layer: 2" title="64:9-64:26: @12[5]: _72 = const main::promoted[0]
|
||||
64:9-64:26: @12[6]: _53 = &(*_72)
|
||||
64:9-64:26: @12[7]: _52 = &(*_53)
|
||||
64:9-64:26: @12[8]: _51 = move _52 as &[&str] (Pointer(Unsize))
|
||||
64:9-64:26: @12[17]: _61 = &(*_43)
|
||||
64:9-64:26: @12[18]: _60 = &_61
|
||||
64:9-64:26: @12[21]: _63 = &(*_44)
|
||||
64:9-64:26: @12[22]: _62 = &_63
|
||||
64:9-64:26: @12[23]: _59 = (move _60, move _62)
|
||||
64:9-64:26: @12[26]: FakeRead(ForMatchedPlace, _59)
|
||||
64:9-64:26: @12[28]: _64 = (_59.0: &&i32)
|
||||
64:9-64:26: @12[30]: _65 = (_59.1: &&i32)
|
||||
64:9-64:26: @12[33]: _67 = &(*_64)
|
||||
64:9-64:26: @12[35]: _68 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
64:9-64:26: @12.Call: _66 = ArgumentV1::new::<&i32>(move _67, move _68) -> [return: bb13, unwind: bb17]
|
||||
64:9-64:26: @13[4]: _70 = &(*_65)
|
||||
64:9-64:26: @13[6]: _71 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
64:9-64:26: @13.Call: _69 = ArgumentV1::new::<&i32>(move _70, move _71) -> [return: bb14, unwind: bb17]
|
||||
64:9-64:26: @14[2]: _58 = [move _66, move _69]
|
||||
64:9-64:26: @14[7]: _57 = &_58
|
||||
64:9-64:26: @14[8]: _56 = &(*_57)
|
||||
64:9-64:26: @14[9]: _55 = move _56 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
64:9-64:26: @14.Call: _50 = Arguments::new_v1(move _51, move _55) -> [return: bb15, unwind: bb17]
|
||||
64:9-64:26: @15.Call: core::panicking::panic_fmt(move _50) -> bb17"><span class="annotation">@10,12,13,14,15⦊</span>assert_eq!(1, 2);<span class="annotation">⦉@10,12,13,14,15</span></span><span><span class="code even" style="--layer: 1" title="64:9-64:26: @11[0]: _37 = const ()"><span class="annotation">⦉@11</span></span></span><span class="code" style="--layer: 0"></span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="66:2-66:2: @16.Return: return"><span class="annotation">@16⦊</span>‸<span class="annotation">⦉@16</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Preview this file as rendered HTML from the github source at:
|
||||
https://htmlpreview.github.io/?https://github.com/rust-lang/rust/blob/master/src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.doctest_crate/doctest_crate.fn_run_in_doctests.-------.InstrumentCoverage.0.html
|
||||
|
||||
For revisions in Pull Requests (PR):
|
||||
* Replace "rust-lang" with the github PR author
|
||||
* Replace "master" with the PR branch name
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>doctest_crate.fn_run_in_doctests - Coverage Spans</title>
|
||||
<style>
|
||||
.line {
|
||||
counter-increment: line;
|
||||
}
|
||||
.line:before {
|
||||
content: counter(line) ": ";
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
font-style: italic;
|
||||
width: 3.8em;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
filter: opacity(50%);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.code {
|
||||
color: #dddddd;
|
||||
background-color: #222222;
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
line-height: 1.4em;
|
||||
border-bottom: 2px solid #222222;
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
}
|
||||
.odd {
|
||||
background-color: #55bbff;
|
||||
color: #223311;
|
||||
}
|
||||
.even {
|
||||
background-color: #ee7756;
|
||||
color: #551133;
|
||||
}
|
||||
.code {
|
||||
--index: calc(var(--layer) - 1);
|
||||
padding-top: calc(var(--index) * 0.15em);
|
||||
filter:
|
||||
hue-rotate(calc(var(--index) * 25deg))
|
||||
saturate(calc(100% - (var(--index) * 2%)))
|
||||
brightness(calc(100% - (var(--index) * 1.5%)));
|
||||
}
|
||||
.annotation {
|
||||
color: #4444ff;
|
||||
font-family: monospace;
|
||||
font-style: italic;
|
||||
display: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body:active .annotation {
|
||||
/* requires holding mouse down anywhere on the page */
|
||||
display: inline-block;
|
||||
}
|
||||
span:hover .annotation {
|
||||
/* requires hover over a span ONLY on its first line */
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="code" style="counter-reset: line 1"><span class="line"><span><span class="code even" style="--layer: 1"><span class="annotation">@0⦊</span>pub fn fn_run_in_doctests(conditional: usize) <span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0">{</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> match </span><span><span class="code even" style="--layer: 1" title="3:11-3:22: @0[0]: FakeRead(ForMatchedPlace, _1)"><span class="annotation">@0⦊</span>conditional<span class="annotation">⦉@0</span></span></span><span class="code" style="--layer: 0"> {</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> 1 => </span><span><span class="code odd" style="--layer: 1" title="4:14-4:30: @7[0]: _0 = const ()"><span class="annotation">@7⦊</span></span></span><span class="code even" style="--layer: 2" title="4:14-4:30: @8[5]: _138 = const fn_run_in_doctests::promoted[0]
|
||||
4:14-4:30: @8[6]: _17 = &(*_138)
|
||||
4:14-4:30: @8[7]: _16 = &(*_17)
|
||||
4:14-4:30: @8[8]: _15 = move _16 as &[&str] (Pointer(Unsize))
|
||||
4:14-4:30: @8[17]: _25 = &(*_7)
|
||||
4:14-4:30: @8[18]: _24 = &_25
|
||||
4:14-4:30: @8[21]: _27 = &(*_8)
|
||||
4:14-4:30: @8[22]: _26 = &_27
|
||||
4:14-4:30: @8[23]: _23 = (move _24, move _26)
|
||||
4:14-4:30: @8[26]: FakeRead(ForMatchedPlace, _23)
|
||||
4:14-4:30: @8[28]: _28 = (_23.0: &&i32)
|
||||
4:14-4:30: @8[30]: _29 = (_23.1: &&i32)
|
||||
4:14-4:30: @8[33]: _31 = &(*_28)
|
||||
4:14-4:30: @8[35]: _32 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
4:14-4:30: @8.Call: _30 = ArgumentV1::new::<&i32>(move _31, move _32) -> [return: bb9, unwind: bb33]
|
||||
4:14-4:30: @9[4]: _34 = &(*_29)
|
||||
4:14-4:30: @9[6]: _35 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
4:14-4:30: @9.Call: _33 = ArgumentV1::new::<&i32>(move _34, move _35) -> [return: bb10, unwind: bb33]
|
||||
4:14-4:30: @10[2]: _22 = [move _30, move _33]
|
||||
4:14-4:30: @10[7]: _21 = &_22
|
||||
4:14-4:30: @10[8]: _20 = &(*_21)
|
||||
4:14-4:30: @10[9]: _19 = move _20 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
4:14-4:30: @10.Call: _14 = Arguments::new_v1(move _15, move _19) -> [return: bb11, unwind: bb33]
|
||||
4:14-4:30: @11.Call: core::panicking::panic_fmt(move _14) -> bb33"><span class="annotation">@6,8,9,10,11⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@6,8,9,10,11</span></span><span><span class="code odd" style="--layer: 1" title="4:14-4:30: @7[0]: _0 = const ()"><span class="annotation">⦉@7</span></span></span><span class="code" style="--layer: 0">, // this is run,</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> 2 => </span><span><span class="code even" style="--layer: 1" title="5:14-5:30: @14[0]: _0 = const ()"><span class="annotation">@14⦊</span></span></span><span class="code even" style="--layer: 2" title="5:14-5:30: @15[5]: _141 = const fn_run_in_doctests::promoted[3]
|
||||
5:14-5:30: @15[6]: _51 = &(*_141)
|
||||
5:14-5:30: @15[7]: _50 = &(*_51)
|
||||
5:14-5:30: @15[8]: _49 = move _50 as &[&str] (Pointer(Unsize))
|
||||
5:14-5:30: @15[17]: _59 = &(*_41)
|
||||
5:14-5:30: @15[18]: _58 = &_59
|
||||
5:14-5:30: @15[21]: _61 = &(*_42)
|
||||
5:14-5:30: @15[22]: _60 = &_61
|
||||
5:14-5:30: @15[23]: _57 = (move _58, move _60)
|
||||
5:14-5:30: @15[26]: FakeRead(ForMatchedPlace, _57)
|
||||
5:14-5:30: @15[28]: _62 = (_57.0: &&i32)
|
||||
5:14-5:30: @15[30]: _63 = (_57.1: &&i32)
|
||||
5:14-5:30: @15[33]: _65 = &(*_62)
|
||||
5:14-5:30: @15[35]: _66 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
5:14-5:30: @15.Call: _64 = ArgumentV1::new::<&i32>(move _65, move _66) -> [return: bb16, unwind: bb33]
|
||||
5:14-5:30: @16[4]: _68 = &(*_63)
|
||||
5:14-5:30: @16[6]: _69 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
5:14-5:30: @16.Call: _67 = ArgumentV1::new::<&i32>(move _68, move _69) -> [return: bb17, unwind: bb33]
|
||||
5:14-5:30: @17[2]: _56 = [move _64, move _67]
|
||||
5:14-5:30: @17[7]: _55 = &_56
|
||||
5:14-5:30: @17[8]: _54 = &(*_55)
|
||||
5:14-5:30: @17[9]: _53 = move _54 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
5:14-5:30: @17.Call: _48 = Arguments::new_v1(move _49, move _53) -> [return: bb18, unwind: bb33]
|
||||
5:14-5:30: @18.Call: core::panicking::panic_fmt(move _48) -> bb33"><span class="annotation">@13,15,16,17,18⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@13,15,16,17,18</span></span><span><span class="code even" style="--layer: 1" title="5:14-5:30: @14[0]: _0 = const ()"><span class="annotation">⦉@14</span></span></span><span class="code" style="--layer: 0">, // this,</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> 3 => </span><span><span class="code odd" style="--layer: 1" title="6:14-6:30: @21[0]: _0 = const ()"><span class="annotation">@21⦊</span></span></span><span class="code even" style="--layer: 2" title="6:14-6:30: @22[5]: _144 = const fn_run_in_doctests::promoted[6]
|
||||
6:14-6:30: @22[6]: _85 = &(*_144)
|
||||
6:14-6:30: @22[7]: _84 = &(*_85)
|
||||
6:14-6:30: @22[8]: _83 = move _84 as &[&str] (Pointer(Unsize))
|
||||
6:14-6:30: @22[17]: _93 = &(*_75)
|
||||
6:14-6:30: @22[18]: _92 = &_93
|
||||
6:14-6:30: @22[21]: _95 = &(*_76)
|
||||
6:14-6:30: @22[22]: _94 = &_95
|
||||
6:14-6:30: @22[23]: _91 = (move _92, move _94)
|
||||
6:14-6:30: @22[26]: FakeRead(ForMatchedPlace, _91)
|
||||
6:14-6:30: @22[28]: _96 = (_91.0: &&i32)
|
||||
6:14-6:30: @22[30]: _97 = (_91.1: &&i32)
|
||||
6:14-6:30: @22[33]: _99 = &(*_96)
|
||||
6:14-6:30: @22[35]: _100 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
6:14-6:30: @22.Call: _98 = ArgumentV1::new::<&i32>(move _99, move _100) -> [return: bb23, unwind: bb33]
|
||||
6:14-6:30: @23[4]: _102 = &(*_97)
|
||||
6:14-6:30: @23[6]: _103 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
6:14-6:30: @23.Call: _101 = ArgumentV1::new::<&i32>(move _102, move _103) -> [return: bb24, unwind: bb33]
|
||||
6:14-6:30: @24[2]: _90 = [move _98, move _101]
|
||||
6:14-6:30: @24[7]: _89 = &_90
|
||||
6:14-6:30: @24[8]: _88 = &(*_89)
|
||||
6:14-6:30: @24[9]: _87 = move _88 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
6:14-6:30: @24.Call: _82 = Arguments::new_v1(move _83, move _87) -> [return: bb25, unwind: bb33]
|
||||
6:14-6:30: @25.Call: core::panicking::panic_fmt(move _82) -> bb33"><span class="annotation">@20,22,23,24,25⦊</span>assert_eq!(1, 1)<span class="annotation">⦉@20,22,23,24,25</span></span><span><span class="code odd" style="--layer: 1" title="6:14-6:30: @21[0]: _0 = const ()"><span class="annotation">⦉@21</span></span></span><span class="code" style="--layer: 0">, // and this too</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> _ => </span><span><span class="code even" style="--layer: 1" title="7:14-7:30: @27[0]: _0 = const ()"><span class="annotation">@27⦊</span></span></span><span class="code even" style="--layer: 2" title="7:14-7:30: @28[5]: _147 = const fn_run_in_doctests::promoted[9]
|
||||
7:14-7:30: @28[6]: _119 = &(*_147)
|
||||
7:14-7:30: @28[7]: _118 = &(*_119)
|
||||
7:14-7:30: @28[8]: _117 = move _118 as &[&str] (Pointer(Unsize))
|
||||
7:14-7:30: @28[17]: _127 = &(*_109)
|
||||
7:14-7:30: @28[18]: _126 = &_127
|
||||
7:14-7:30: @28[21]: _129 = &(*_110)
|
||||
7:14-7:30: @28[22]: _128 = &_129
|
||||
7:14-7:30: @28[23]: _125 = (move _126, move _128)
|
||||
7:14-7:30: @28[26]: FakeRead(ForMatchedPlace, _125)
|
||||
7:14-7:30: @28[28]: _130 = (_125.0: &&i32)
|
||||
7:14-7:30: @28[30]: _131 = (_125.1: &&i32)
|
||||
7:14-7:30: @28[33]: _133 = &(*_130)
|
||||
7:14-7:30: @28[35]: _134 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
7:14-7:30: @28.Call: _132 = ArgumentV1::new::<&i32>(move _133, move _134) -> [return: bb29, unwind: bb33]
|
||||
7:14-7:30: @29[4]: _136 = &(*_131)
|
||||
7:14-7:30: @29[6]: _137 = <&i32 as Debug>::fmt as for<'r, 's, 't0> fn(&'r &i32, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer))
|
||||
7:14-7:30: @29.Call: _135 = ArgumentV1::new::<&i32>(move _136, move _137) -> [return: bb30, unwind: bb33]
|
||||
7:14-7:30: @30[2]: _124 = [move _132, move _135]
|
||||
7:14-7:30: @30[7]: _123 = &_124
|
||||
7:14-7:30: @30[8]: _122 = &(*_123)
|
||||
7:14-7:30: @30[9]: _121 = move _122 as &[std::fmt::ArgumentV1] (Pointer(Unsize))
|
||||
7:14-7:30: @30.Call: _116 = Arguments::new_v1(move _117, move _121) -> [return: bb31, unwind: bb33]
|
||||
7:14-7:30: @31.Call: core::panicking::panic_fmt(move _116) -> bb33"><span class="annotation">@26,28,29,30,31⦊</span>assert_eq!(1, 2)<span class="annotation">⦉@26,28,29,30,31</span></span><span><span class="code even" style="--layer: 1" title="7:14-7:30: @27[0]: _0 = const ()"><span class="annotation">⦉@27</span></span></span><span class="code" style="--layer: 0">, // however this is not</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
|
||||
<span class="line"><span class="code" style="--layer: 0">}</span><span><span class="code odd" style="--layer: 1" title="9:2-9:2: @32.Return: return"><span class="annotation">@32⦊</span>‸<span class="annotation">⦉@32</span></span></span></span></div>
|
||||
</body>
|
||||
</html>
|
@ -1,3 +1,3 @@
|
||||
# Directory "instrument-coverage" supports the tests at prefix ../instrument-coverage-*
|
||||
# Directory "coverage" supports the tests at prefix ../coverage-*
|
||||
|
||||
# Use ./x.py [options] test src/test/run-make-fulldeps/instrument-coverage to run all related tests.
|
||||
# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests.
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Common Makefile include for Rust `run-make-fulldeps/instrument-coverage-* tests. Include this
|
||||
# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this
|
||||
# file with the line:
|
||||
#
|
||||
# -include ../instrument-coverage/coverage_tools.mk
|
||||
# -include ../coverage/coverage_tools.mk
|
||||
|
||||
-include ../tools.mk
|
||||
|
||||
|
66
src/test/run-make-fulldeps/coverage/doctest.rs
Normal file
66
src/test/run-make-fulldeps/coverage/doctest.rs
Normal file
@ -0,0 +1,66 @@
|
||||
//! This test ensures that code from doctests is properly re-mapped.
|
||||
//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
|
||||
//!
|
||||
//! Just some random code:
|
||||
//! ```
|
||||
//! if true {
|
||||
//! // this is executed!
|
||||
//! assert_eq!(1, 1);
|
||||
//! } else {
|
||||
//! // this is not!
|
||||
//! assert_eq!(1, 2);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! doctest testing external code:
|
||||
//! ```
|
||||
//! extern crate doctest_crate;
|
||||
//! doctest_crate::fn_run_in_doctests(1);
|
||||
//! ```
|
||||
//!
|
||||
//! doctest returning a result:
|
||||
//! ```
|
||||
//! #[derive(Debug)]
|
||||
//! struct SomeError;
|
||||
//! let mut res = Err(SomeError);
|
||||
//! if res.is_ok() {
|
||||
//! res?;
|
||||
//! } else {
|
||||
//! res = Ok(0);
|
||||
//! }
|
||||
//! // need to be explicit because rustdoc cant infer the return type
|
||||
//! Ok::<(), SomeError>(())
|
||||
//! ```
|
||||
//!
|
||||
//! doctest with custom main:
|
||||
//! ```
|
||||
//! #[derive(Debug)]
|
||||
//! struct SomeError;
|
||||
//!
|
||||
//! extern crate doctest_crate;
|
||||
//!
|
||||
//! fn doctest_main() -> Result<(), SomeError> {
|
||||
//! doctest_crate::fn_run_in_doctests(2);
|
||||
//! Ok(())
|
||||
//! }
|
||||
//!
|
||||
//! // this `main` is not shown as covered, as it clashes with all the other
|
||||
//! // `main` functions that were automatically generated for doctests
|
||||
//! fn main() -> Result<(), SomeError> {
|
||||
//! doctest_main()
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
/// doctest attached to fn testing external code:
|
||||
/// ```
|
||||
/// extern crate doctest_crate;
|
||||
/// doctest_crate::fn_run_in_doctests(3);
|
||||
/// ```
|
||||
///
|
||||
fn main() {
|
||||
if true {
|
||||
assert_eq!(1, 1);
|
||||
} else {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
}
|
9
src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs
Normal file
9
src/test/run-make-fulldeps/coverage/lib/doctest_crate.rs
Normal file
@ -0,0 +1,9 @@
|
||||
/// A function run only from within doctests
|
||||
pub fn fn_run_in_doctests(conditional: usize) {
|
||||
match conditional {
|
||||
1 => assert_eq!(1, 1), // this is run,
|
||||
2 => assert_eq!(1, 1), // this,
|
||||
3 => assert_eq!(1, 1), // and this too
|
||||
_ => assert_eq!(1, 2), // however this is not
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user