Skip to content

Commit 830ceaa

Browse files
committedDec 19, 2020
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. Part of issue #79417.
·
1.88.01.50.0
1 parent 3d9ada6 commit 830ceaa

File tree

15 files changed

+596
-56
lines changed

15 files changed

+596
-56
lines changed
 

‎compiler/rustc_mir/src/transform/coverage/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use rustc_middle::mir::{
3030
};
3131
use rustc_middle::ty::TyCtxt;
3232
use rustc_span::def_id::DefId;
33+
use rustc_span::source_map::SourceMap;
3334
use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol};
3435

3536
/// A simple error message wrapper for `coverage::Error`s.
@@ -311,7 +312,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
311312
self.mir_body,
312313
counter_kind,
313314
self.bcb_leader_bb(bcb),
314-
Some(make_code_region(file_name, &self.source_file, span, body_span)),
315+
Some(make_code_region(source_map, file_name, &self.source_file, span, body_span)),
315316
);
316317
}
317318
}
@@ -489,6 +490,7 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: Co
489490

490491
/// Convert the Span into its file name, start line and column, and end line and column
491492
fn make_code_region(
493+
source_map: &SourceMap,
492494
file_name: Symbol,
493495
source_file: &Lrc<SourceFile>,
494496
span: Span,
@@ -508,6 +510,8 @@ fn make_code_region(
508510
} else {
509511
source_file.lookup_file_pos(span.hi())
510512
};
513+
let start_line = source_map.doctest_offset_line(&source_file.name, start_line);
514+
let end_line = source_map.doctest_offset_line(&source_file.name, end_line);
511515
CodeRegion {
512516
file_name,
513517
start_line: start_line as u32,

‎compiler/rustc_span/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl std::fmt::Display for FileName {
182182
use FileName::*;
183183
match *self {
184184
Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()),
185-
// FIXME: might be nice to display both compoments of Devirtualized.
185+
// FIXME: might be nice to display both components of Devirtualized.
186186
// But for now (to backport fix for issue #70924), best to not
187187
// perturb diagnostics so its obvious test suite still works.
188188
Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => {

‎src/librustdoc/doctest.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,10 @@ fn run_test(
247247
edition: Edition,
248248
outdir: DirState,
249249
path: PathBuf,
250+
test_id: &str,
250251
) -> Result<(), TestFailure> {
251252
let (test, line_offset, supports_color) =
252-
make_test(test, Some(cratename), as_test_harness, opts, edition);
253+
make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id));
253254

254255
let output_file = outdir.path().join("rust_out");
255256

@@ -387,6 +388,7 @@ crate fn make_test(
387388
dont_insert_main: bool,
388389
opts: &TestOptions,
389390
edition: Edition,
391+
test_id: Option<&str>,
390392
) -> (String, usize, bool) {
391393
let (crate_attrs, everything_else, crates) = partition_source(s);
392394
let everything_else = everything_else.trim();
@@ -542,16 +544,40 @@ crate fn make_test(
542544
prog.push_str(everything_else);
543545
} else {
544546
let returns_result = everything_else.trim_end().ends_with("(())");
547+
// Give each doctest main function a unique name.
548+
// This is for example needed for the tooling around `-Z instrument-coverage`.
549+
let inner_fn_name = if let Some(test_id) = test_id {
550+
format!("_doctest_main_{}", test_id)
551+
} else {
552+
"_inner".into()
553+
};
545554
let (main_pre, main_post) = if returns_result {
546555
(
547-
"fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
548-
"}\n_inner().unwrap() }",
556+
format!(
557+
"fn main() {{ fn {}() -> Result<(), impl core::fmt::Debug> {{\n",
558+
inner_fn_name
559+
),
560+
format!("\n}}; {}().unwrap() }}", inner_fn_name),
561+
)
562+
} else if test_id.is_some() {
563+
(
564+
format!("fn main() {{ fn {}() {{\n", inner_fn_name),
565+
format!("\n}}; {}() }}", inner_fn_name),
549566
)
550567
} else {
551-
("fn main() {\n", "\n}")
568+
("fn main() {\n".into(), "\n}".into())
552569
};
553-
prog.extend([main_pre, everything_else, main_post].iter().cloned());
570+
// Note on newlines: We insert a line/newline *before*, and *after*
571+
// the doctest and adjust the `line_offset` accordingly.
572+
// In the case of `-Z instrument-coverage`, this means that the generated
573+
// inner `main` function spans from the doctest opening codeblock to the
574+
// closing one. For example
575+
// /// ``` <- start of the inner main
576+
// /// <- code under doctest
577+
// /// ``` <- end of the inner main
554578
line_offset += 1;
579+
580+
prog.extend([&main_pre, everything_else, &main_post].iter().cloned());
555581
}
556582

557583
debug!("final doctest:\n{}", prog);
@@ -749,28 +775,24 @@ impl Tester for Collector {
749775
_ => PathBuf::from(r"doctest.rs"),
750776
};
751777

778+
// For example `module/file.rs` would become `module_file_rs`
779+
let file = filename
780+
.to_string()
781+
.chars()
782+
.map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
783+
.collect::<String>();
784+
let test_id = format!(
785+
"{file}_{line}_{number}",
786+
file = file,
787+
line = line,
788+
number = {
789+
// Increases the current test number, if this file already
790+
// exists or it creates a new entry with a test number of 0.
791+
self.visited_tests.entry((file.clone(), line)).and_modify(|v| *v += 1).or_insert(0)
792+
},
793+
);
752794
let outdir = if let Some(mut path) = options.persist_doctests.clone() {
753-
// For example `module/file.rs` would become `module_file_rs`
754-
let folder_name = filename
755-
.to_string()
756-
.chars()
757-
.map(|c| if c == '\\' || c == '/' || c == '.' { '_' } else { c })
758-
.collect::<String>();
759-
760-
path.push(format!(
761-
"{krate}_{file}_{line}_{number}",
762-
krate = cratename,
763-
file = folder_name,
764-
line = line,
765-
number = {
766-
// Increases the current test number, if this file already
767-
// exists or it creates a new entry with a test number of 0.
768-
self.visited_tests
769-
.entry((folder_name.clone(), line))
770-
.and_modify(|v| *v += 1)
771-
.or_insert(0)
772-
},
773-
));
795+
path.push(&test_id);
774796

775797
std::fs::create_dir_all(&path)
776798
.expect("Couldn't create directory for doctest executables");
@@ -817,6 +839,7 @@ impl Tester for Collector {
817839
edition,
818840
outdir,
819841
path,
842+
&test_id,
820843
);
821844

822845
if let Err(err) = res {

‎src/librustdoc/doctest/tests.rs

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() {
1111
assert_eq!(2+2, 4);
1212
}"
1313
.to_string();
14-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
14+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
1515
assert_eq!((output, len), (expected, 2));
1616
}
1717

@@ -26,7 +26,7 @@ fn main() {
2626
assert_eq!(2+2, 4);
2727
}"
2828
.to_string();
29-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
29+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
3030
assert_eq!((output, len), (expected, 2));
3131
}
3232

@@ -44,7 +44,7 @@ use asdf::qwop;
4444
assert_eq!(2+2, 4);
4545
}"
4646
.to_string();
47-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
47+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
4848
assert_eq!((output, len), (expected, 3));
4949
}
5050

@@ -61,7 +61,7 @@ use asdf::qwop;
6161
assert_eq!(2+2, 4);
6262
}"
6363
.to_string();
64-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
64+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
6565
assert_eq!((output, len), (expected, 2));
6666
}
6767

@@ -79,7 +79,7 @@ use std::*;
7979
assert_eq!(2+2, 4);
8080
}"
8181
.to_string();
82-
let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION);
82+
let (output, len, _) = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION, None);
8383
assert_eq!((output, len), (expected, 2));
8484
}
8585

@@ -98,7 +98,7 @@ use asdf::qwop;
9898
assert_eq!(2+2, 4);
9999
}"
100100
.to_string();
101-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
101+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
102102
assert_eq!((output, len), (expected, 2));
103103
}
104104

@@ -115,7 +115,7 @@ use asdf::qwop;
115115
assert_eq!(2+2, 4);
116116
}"
117117
.to_string();
118-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
118+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
119119
assert_eq!((output, len), (expected, 2));
120120
}
121121

@@ -134,7 +134,7 @@ use asdf::qwop;
134134
assert_eq!(2+2, 4);
135135
}"
136136
.to_string();
137-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
137+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
138138
assert_eq!((output, len), (expected, 3));
139139

140140
// Adding more will also bump the returned line offset.
@@ -147,7 +147,7 @@ use asdf::qwop;
147147
assert_eq!(2+2, 4);
148148
}"
149149
.to_string();
150-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
150+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
151151
assert_eq!((output, len), (expected, 4));
152152
}
153153

@@ -164,7 +164,7 @@ fn main() {
164164
assert_eq!(2+2, 4);
165165
}"
166166
.to_string();
167-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
167+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
168168
assert_eq!((output, len), (expected, 2));
169169
}
170170

@@ -180,7 +180,7 @@ fn main() {
180180
assert_eq!(2+2, 4);
181181
}"
182182
.to_string();
183-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
183+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
184184
assert_eq!((output, len), (expected, 1));
185185
}
186186

@@ -196,7 +196,7 @@ fn main() {
196196
assert_eq!(2+2, 4);
197197
}"
198198
.to_string();
199-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
199+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
200200
assert_eq!((output, len), (expected, 2));
201201
}
202202

@@ -210,7 +210,7 @@ assert_eq!(2+2, 4);";
210210
//Ceci n'est pas une `fn main`
211211
assert_eq!(2+2, 4);"
212212
.to_string();
213-
let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION);
213+
let (output, len, _) = make_test(input, None, true, &opts, DEFAULT_EDITION, None);
214214
assert_eq!((output, len), (expected, 1));
215215
}
216216

@@ -224,7 +224,7 @@ fn make_test_display_warnings() {
224224
assert_eq!(2+2, 4);
225225
}"
226226
.to_string();
227-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
227+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
228228
assert_eq!((output, len), (expected, 1));
229229
}
230230

@@ -242,7 +242,7 @@ assert_eq!(2+2, 4);
242242
}"
243243
.to_string();
244244

245-
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION);
245+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
246246
assert_eq!((output, len), (expected, 2));
247247

248248
let input = "extern crate hella_qwop;
@@ -256,7 +256,7 @@ assert_eq!(asdf::foo, 4);
256256
}"
257257
.to_string();
258258

259-
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
259+
let (output, len, _) = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION, None);
260260
assert_eq!((output, len), (expected, 3));
261261
}
262262

@@ -274,6 +274,41 @@ test_wrapper! {
274274
}"
275275
.to_string();
276276

277-
let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION);
277+
let (output, len, _) = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION, None);
278278
assert_eq!((output, len), (expected, 1));
279279
}
280+
281+
#[test]
282+
fn make_test_returns_result() {
283+
// creates an inner function and unwraps it
284+
let opts = TestOptions::default();
285+
let input = "use std::io;
286+
let mut input = String::new();
287+
io::stdin().read_line(&mut input)?;
288+
Ok::<(), io:Error>(())";
289+
let expected = "#![allow(unused)]
290+
fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {
291+
use std::io;
292+
let mut input = String::new();
293+
io::stdin().read_line(&mut input)?;
294+
Ok::<(), io:Error>(())
295+
}; _inner().unwrap() }"
296+
.to_string();
297+
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
298+
assert_eq!((output, len), (expected, 2));
299+
}
300+
301+
#[test]
302+
fn make_test_named_wrapper() {
303+
// creates an inner function with a specific name
304+
let opts = TestOptions::default();
305+
let input = "assert_eq!(2+2, 4);";
306+
let expected = "#![allow(unused)]
307+
fn main() { fn _doctest_main_some_unique_name() {
308+
assert_eq!(2+2, 4);
309+
}; _doctest_main_some_unique_name() }"
310+
.to_string();
311+
let (output, len, _) =
312+
make_test(input, None, false, &opts, DEFAULT_EDITION, Some("some_unique_name"));
313+
assert_eq!((output, len), (expected, 2));
314+
}

‎src/librustdoc/html/markdown.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
248248
.join("\n");
249249
let krate = krate.as_ref().map(|s| &**s);
250250
let (test, _, _) =
251-
doctest::make_test(&test, krate, false, &Default::default(), edition);
251+
doctest::make_test(&test, krate, false, &Default::default(), edition, None);
252252
let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };
253253

254254
let edition_string = format!("&amp;edition={}", edition);

‎src/test/run-make-fulldeps/coverage-reports/Makefile

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ endif
9898
# Run it in order to generate some profiling data,
9999
# with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
100100
# output the coverage stats for this run.
101-
LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
101+
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
102102
$(call RUN,$@) || \
103103
( \
104104
status=$$?; \
@@ -108,9 +108,16 @@ endif
108108
) \
109109
)
110110

111+
# Run it through rustdoc as well to cover doctests
112+
LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p.profraw \
113+
$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
114+
$$( grep -q '^\/\/ require-rust-edition-2018' $(SOURCEDIR)/$@.rs && echo "--edition=2018" ) \
115+
-L "$(TMPDIR)" -Zinstrument-coverage \
116+
-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
117+
111118
# Postprocess the profiling data so it can be used by the llvm-cov tool
112119
"$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
113-
"$(TMPDIR)"/$@.profraw \
120+
"$(TMPDIR)"/$@-*.profraw \
114121
-o "$(TMPDIR)"/$@.profdata
115122

116123
# Generate a coverage report using `llvm-cov show`.
@@ -121,8 +128,15 @@ endif
121128
--show-line-counts-or-regions \
122129
--instr-profile="$(TMPDIR)"/$@.profdata \
123130
$(call BIN,"$(TMPDIR)"/$@) \
124-
> "$(TMPDIR)"/actual_show_coverage.$@.txt \
125-
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt || \
131+
$$( \
132+
for file in $(TMPDIR)/rustdoc-$@/*/rust_out; \
133+
do \
134+
[[ -x $$file ]] && printf "%s %s " -object $$file; \
135+
done \
136+
) \
137+
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
138+
| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
139+
> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
126140
( status=$$? ; \
127141
>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
128142
exit $$status \
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
../coverage/doctest.rs:
2+
1| |//! This test ensures that code from doctests is properly re-mapped.
3+
2| |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
4+
3| |//!
5+
4| |//! Just some random code:
6+
5| 1|//! ```
7+
6| 1|//! if true {
8+
7| |//! // this is executed!
9+
8| 1|//! assert_eq!(1, 1);
10+
9| |//! } else {
11+
10| |//! // this is not!
12+
11| |//! assert_eq!(1, 2);
13+
12| |//! }
14+
13| 1|//! ```
15+
14| |//!
16+
15| |//! doctest testing external code:
17+
16| |//! ```
18+
17| 1|//! extern crate doctest_crate;
19+
18| 1|//! doctest_crate::fn_run_in_doctests(1);
20+
19| 1|//! ```
21+
20| |//!
22+
21| |//! doctest returning a result:
23+
22| 1|//! ```
24+
23| 1|//! #[derive(Debug)]
25+
24| 1|//! struct SomeError;
26+
25| 1|//! let mut res = Err(SomeError);
27+
26| 1|//! if res.is_ok() {
28+
27| 0|//! res?;
29+
28| 1|//! } else {
30+
29| 1|//! res = Ok(0);
31+
30| 1|//! }
32+
31| |//! // need to be explicit because rustdoc cant infer the return type
33+
32| 1|//! Ok::<(), SomeError>(())
34+
33| 1|//! ```
35+
34| |//!
36+
35| |//! doctest with custom main:
37+
36| |//! ```
38+
37| |//! #[derive(Debug)]
39+
38| |//! struct SomeError;
40+
39| |//!
41+
40| |//! extern crate doctest_crate;
42+
41| |//!
43+
42| 1|//! fn doctest_main() -> Result<(), SomeError> {
44+
43| 1|//! doctest_crate::fn_run_in_doctests(2);
45+
44| 1|//! Ok(())
46+
45| 1|//! }
47+
46| |//!
48+
47| |//! // this `main` is not shown as covered, as it clashes with all the other
49+
48| |//! // `main` functions that were automatically generated for doctests
50+
49| |//! fn main() -> Result<(), SomeError> {
51+
50| |//! doctest_main()
52+
51| |//! }
53+
52| |//! ```
54+
53| |
55+
54| |/// doctest attached to fn testing external code:
56+
55| |/// ```
57+
56| 1|/// extern crate doctest_crate;
58+
57| 1|/// doctest_crate::fn_run_in_doctests(3);
59+
58| 1|/// ```
60+
59| |///
61+
60| 1|fn main() {
62+
61| 1| if true {
63+
62| 1| assert_eq!(1, 1);
64+
63| | } else {
65+
64| | assert_eq!(1, 2);
66+
65| | }
67+
66| 1|}
68+
69+
../coverage/lib/doctest_crate.rs:
70+
1| |/// A function run only from within doctests
71+
2| 3|pub fn fn_run_in_doctests(conditional: usize) {
72+
3| 3| match conditional {
73+
4| 1| 1 => assert_eq!(1, 1), // this is run,
74+
5| 1| 2 => assert_eq!(1, 1), // this,
75+
6| 1| 3 => assert_eq!(1, 1), // and this too
76+
7| 0| _ => assert_eq!(1, 2), // however this is not
77+
8| | }
78+
9| 3|}
79+

‎src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
2020
19| 2|}
2121
------------------
22-
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
22+
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
2323
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
2424
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
2525
| 19| 1|}
2626
------------------
27-
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
27+
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
2828
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
2929
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
3030
| 19| 1|}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python
2+
3+
import sys
4+
5+
# Normalize file paths in output
6+
for line in sys.stdin:
7+
if line.startswith("..") and line.rstrip().endswith(".rs:"):
8+
print(line.replace("\\", "/"), end='')
9+
else:
10+
print(line, end='')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<!DOCTYPE html>
2+
<!--
3+
4+
Preview this file as rendered HTML from the github source at:
5+
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
6+
7+
For revisions in Pull Requests (PR):
8+
* Replace "rust-lang" with the github PR author
9+
* Replace "master" with the PR branch name
10+
11+
-->
12+
<html>
13+
<head>
14+
<title>doctest.main - Coverage Spans</title>
15+
<style>
16+
.line {
17+
counter-increment: line;
18+
}
19+
.line:before {
20+
content: counter(line) ": ";
21+
font-family: Menlo, Monaco, monospace;
22+
font-style: italic;
23+
width: 3.8em;
24+
display: inline-block;
25+
text-align: right;
26+
filter: opacity(50%);
27+
-webkit-user-select: none;
28+
}
29+
.code {
30+
color: #dddddd;
31+
background-color: #222222;
32+
font-family: Menlo, Monaco, monospace;
33+
line-height: 1.4em;
34+
border-bottom: 2px solid #222222;
35+
white-space: pre;
36+
display: inline-block;
37+
}
38+
.odd {
39+
background-color: #55bbff;
40+
color: #223311;
41+
}
42+
.even {
43+
background-color: #ee7756;
44+
color: #551133;
45+
}
46+
.code {
47+
--index: calc(var(--layer) - 1);
48+
padding-top: calc(var(--index) * 0.15em);
49+
filter:
50+
hue-rotate(calc(var(--index) * 25deg))
51+
saturate(calc(100% - (var(--index) * 2%)))
52+
brightness(calc(100% - (var(--index) * 1.5%)));
53+
}
54+
.annotation {
55+
color: #4444ff;
56+
font-family: monospace;
57+
font-style: italic;
58+
display: none;
59+
-webkit-user-select: none;
60+
}
61+
body:active .annotation {
62+
/* requires holding mouse down anywhere on the page */
63+
display: inline-block;
64+
}
65+
span:hover .annotation {
66+
/* requires hover over a span ONLY on its first line */
67+
display: inline-block;
68+
}
69+
</style>
70+
</head>
71+
<body>
72+
<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>
73+
<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
74+
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>
75+
<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]
76+
62:9-62:26: @6[6]: _18 = &amp;(*_75)
77+
62:9-62:26: @6[7]: _17 = &amp;(*_18)
78+
62:9-62:26: @6[8]: _16 = move _17 as &amp;[&amp;str] (Pointer(Unsize))
79+
62:9-62:26: @6[17]: _26 = &amp;(*_8)
80+
62:9-62:26: @6[18]: _25 = &amp;_26
81+
62:9-62:26: @6[21]: _28 = &amp;(*_9)
82+
62:9-62:26: @6[22]: _27 = &amp;_28
83+
62:9-62:26: @6[23]: _24 = (move _25, move _27)
84+
62:9-62:26: @6[26]: FakeRead(ForMatchedPlace, _24)
85+
62:9-62:26: @6[28]: _29 = (_24.0: &amp;&amp;i32)
86+
62:9-62:26: @6[30]: _30 = (_24.1: &amp;&amp;i32)
87+
62:9-62:26: @6[33]: _32 = &amp;(*_29)
88+
62:9-62:26: @6[35]: _33 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
89+
62:9-62:26: @6.Call: _31 = ArgumentV1::new::&lt;&amp;i32&gt;(move _32, move _33) -&gt; [return: bb7, unwind: bb17]
90+
62:9-62:26: @7[4]: _35 = &amp;(*_30)
91+
62:9-62:26: @7[6]: _36 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
92+
62:9-62:26: @7.Call: _34 = ArgumentV1::new::&lt;&amp;i32&gt;(move _35, move _36) -&gt; [return: bb8, unwind: bb17]
93+
62:9-62:26: @8[2]: _23 = [move _31, move _34]
94+
62:9-62:26: @8[7]: _22 = &amp;_23
95+
62:9-62:26: @8[8]: _21 = &amp;(*_22)
96+
62:9-62:26: @8[9]: _20 = move _21 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
97+
62:9-62:26: @8.Call: _15 = Arguments::new_v1(move _16, move _20) -&gt; [return: bb9, unwind: bb17]
98+
62:9-62:26: @9.Call: core::panicking::panic_fmt(move _15) -&gt; 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>
99+
<span class="line"><span class="code" style="--layer: 0"> } else {</span></span>
100+
<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]
101+
64:9-64:26: @12[6]: _53 = &amp;(*_72)
102+
64:9-64:26: @12[7]: _52 = &amp;(*_53)
103+
64:9-64:26: @12[8]: _51 = move _52 as &amp;[&amp;str] (Pointer(Unsize))
104+
64:9-64:26: @12[17]: _61 = &amp;(*_43)
105+
64:9-64:26: @12[18]: _60 = &amp;_61
106+
64:9-64:26: @12[21]: _63 = &amp;(*_44)
107+
64:9-64:26: @12[22]: _62 = &amp;_63
108+
64:9-64:26: @12[23]: _59 = (move _60, move _62)
109+
64:9-64:26: @12[26]: FakeRead(ForMatchedPlace, _59)
110+
64:9-64:26: @12[28]: _64 = (_59.0: &amp;&amp;i32)
111+
64:9-64:26: @12[30]: _65 = (_59.1: &amp;&amp;i32)
112+
64:9-64:26: @12[33]: _67 = &amp;(*_64)
113+
64:9-64:26: @12[35]: _68 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
114+
64:9-64:26: @12.Call: _66 = ArgumentV1::new::&lt;&amp;i32&gt;(move _67, move _68) -&gt; [return: bb13, unwind: bb17]
115+
64:9-64:26: @13[4]: _70 = &amp;(*_65)
116+
64:9-64:26: @13[6]: _71 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
117+
64:9-64:26: @13.Call: _69 = ArgumentV1::new::&lt;&amp;i32&gt;(move _70, move _71) -&gt; [return: bb14, unwind: bb17]
118+
64:9-64:26: @14[2]: _58 = [move _66, move _69]
119+
64:9-64:26: @14[7]: _57 = &amp;_58
120+
64:9-64:26: @14[8]: _56 = &amp;(*_57)
121+
64:9-64:26: @14[9]: _55 = move _56 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
122+
64:9-64:26: @14.Call: _50 = Arguments::new_v1(move _51, move _55) -&gt; [return: bb15, unwind: bb17]
123+
64:9-64:26: @15.Call: core::panicking::panic_fmt(move _50) -&gt; 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>
124+
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
125+
<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>
126+
</body>
127+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<!DOCTYPE html>
2+
<!--
3+
4+
Preview this file as rendered HTML from the github source at:
5+
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
6+
7+
For revisions in Pull Requests (PR):
8+
* Replace "rust-lang" with the github PR author
9+
* Replace "master" with the PR branch name
10+
11+
-->
12+
<html>
13+
<head>
14+
<title>doctest_crate.fn_run_in_doctests - Coverage Spans</title>
15+
<style>
16+
.line {
17+
counter-increment: line;
18+
}
19+
.line:before {
20+
content: counter(line) ": ";
21+
font-family: Menlo, Monaco, monospace;
22+
font-style: italic;
23+
width: 3.8em;
24+
display: inline-block;
25+
text-align: right;
26+
filter: opacity(50%);
27+
-webkit-user-select: none;
28+
}
29+
.code {
30+
color: #dddddd;
31+
background-color: #222222;
32+
font-family: Menlo, Monaco, monospace;
33+
line-height: 1.4em;
34+
border-bottom: 2px solid #222222;
35+
white-space: pre;
36+
display: inline-block;
37+
}
38+
.odd {
39+
background-color: #55bbff;
40+
color: #223311;
41+
}
42+
.even {
43+
background-color: #ee7756;
44+
color: #551133;
45+
}
46+
.code {
47+
--index: calc(var(--layer) - 1);
48+
padding-top: calc(var(--index) * 0.15em);
49+
filter:
50+
hue-rotate(calc(var(--index) * 25deg))
51+
saturate(calc(100% - (var(--index) * 2%)))
52+
brightness(calc(100% - (var(--index) * 1.5%)));
53+
}
54+
.annotation {
55+
color: #4444ff;
56+
font-family: monospace;
57+
font-style: italic;
58+
display: none;
59+
-webkit-user-select: none;
60+
}
61+
body:active .annotation {
62+
/* requires holding mouse down anywhere on the page */
63+
display: inline-block;
64+
}
65+
span:hover .annotation {
66+
/* requires hover over a span ONLY on its first line */
67+
display: inline-block;
68+
}
69+
</style>
70+
</head>
71+
<body>
72+
<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>
73+
<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>
74+
<span class="line"><span class="code" style="--layer: 0"> 1 =&gt; </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]
75+
4:14-4:30: @8[6]: _17 = &amp;(*_138)
76+
4:14-4:30: @8[7]: _16 = &amp;(*_17)
77+
4:14-4:30: @8[8]: _15 = move _16 as &amp;[&amp;str] (Pointer(Unsize))
78+
4:14-4:30: @8[17]: _25 = &amp;(*_7)
79+
4:14-4:30: @8[18]: _24 = &amp;_25
80+
4:14-4:30: @8[21]: _27 = &amp;(*_8)
81+
4:14-4:30: @8[22]: _26 = &amp;_27
82+
4:14-4:30: @8[23]: _23 = (move _24, move _26)
83+
4:14-4:30: @8[26]: FakeRead(ForMatchedPlace, _23)
84+
4:14-4:30: @8[28]: _28 = (_23.0: &amp;&amp;i32)
85+
4:14-4:30: @8[30]: _29 = (_23.1: &amp;&amp;i32)
86+
4:14-4:30: @8[33]: _31 = &amp;(*_28)
87+
4:14-4:30: @8[35]: _32 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
88+
4:14-4:30: @8.Call: _30 = ArgumentV1::new::&lt;&amp;i32&gt;(move _31, move _32) -&gt; [return: bb9, unwind: bb33]
89+
4:14-4:30: @9[4]: _34 = &amp;(*_29)
90+
4:14-4:30: @9[6]: _35 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
91+
4:14-4:30: @9.Call: _33 = ArgumentV1::new::&lt;&amp;i32&gt;(move _34, move _35) -&gt; [return: bb10, unwind: bb33]
92+
4:14-4:30: @10[2]: _22 = [move _30, move _33]
93+
4:14-4:30: @10[7]: _21 = &amp;_22
94+
4:14-4:30: @10[8]: _20 = &amp;(*_21)
95+
4:14-4:30: @10[9]: _19 = move _20 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
96+
4:14-4:30: @10.Call: _14 = Arguments::new_v1(move _15, move _19) -&gt; [return: bb11, unwind: bb33]
97+
4:14-4:30: @11.Call: core::panicking::panic_fmt(move _14) -&gt; 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>
98+
<span class="line"><span class="code" style="--layer: 0"> 2 =&gt; </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]
99+
5:14-5:30: @15[6]: _51 = &amp;(*_141)
100+
5:14-5:30: @15[7]: _50 = &amp;(*_51)
101+
5:14-5:30: @15[8]: _49 = move _50 as &amp;[&amp;str] (Pointer(Unsize))
102+
5:14-5:30: @15[17]: _59 = &amp;(*_41)
103+
5:14-5:30: @15[18]: _58 = &amp;_59
104+
5:14-5:30: @15[21]: _61 = &amp;(*_42)
105+
5:14-5:30: @15[22]: _60 = &amp;_61
106+
5:14-5:30: @15[23]: _57 = (move _58, move _60)
107+
5:14-5:30: @15[26]: FakeRead(ForMatchedPlace, _57)
108+
5:14-5:30: @15[28]: _62 = (_57.0: &amp;&amp;i32)
109+
5:14-5:30: @15[30]: _63 = (_57.1: &amp;&amp;i32)
110+
5:14-5:30: @15[33]: _65 = &amp;(*_62)
111+
5:14-5:30: @15[35]: _66 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
112+
5:14-5:30: @15.Call: _64 = ArgumentV1::new::&lt;&amp;i32&gt;(move _65, move _66) -&gt; [return: bb16, unwind: bb33]
113+
5:14-5:30: @16[4]: _68 = &amp;(*_63)
114+
5:14-5:30: @16[6]: _69 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
115+
5:14-5:30: @16.Call: _67 = ArgumentV1::new::&lt;&amp;i32&gt;(move _68, move _69) -&gt; [return: bb17, unwind: bb33]
116+
5:14-5:30: @17[2]: _56 = [move _64, move _67]
117+
5:14-5:30: @17[7]: _55 = &amp;_56
118+
5:14-5:30: @17[8]: _54 = &amp;(*_55)
119+
5:14-5:30: @17[9]: _53 = move _54 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
120+
5:14-5:30: @17.Call: _48 = Arguments::new_v1(move _49, move _53) -&gt; [return: bb18, unwind: bb33]
121+
5:14-5:30: @18.Call: core::panicking::panic_fmt(move _48) -&gt; 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>
122+
<span class="line"><span class="code" style="--layer: 0"> 3 =&gt; </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]
123+
6:14-6:30: @22[6]: _85 = &amp;(*_144)
124+
6:14-6:30: @22[7]: _84 = &amp;(*_85)
125+
6:14-6:30: @22[8]: _83 = move _84 as &amp;[&amp;str] (Pointer(Unsize))
126+
6:14-6:30: @22[17]: _93 = &amp;(*_75)
127+
6:14-6:30: @22[18]: _92 = &amp;_93
128+
6:14-6:30: @22[21]: _95 = &amp;(*_76)
129+
6:14-6:30: @22[22]: _94 = &amp;_95
130+
6:14-6:30: @22[23]: _91 = (move _92, move _94)
131+
6:14-6:30: @22[26]: FakeRead(ForMatchedPlace, _91)
132+
6:14-6:30: @22[28]: _96 = (_91.0: &amp;&amp;i32)
133+
6:14-6:30: @22[30]: _97 = (_91.1: &amp;&amp;i32)
134+
6:14-6:30: @22[33]: _99 = &amp;(*_96)
135+
6:14-6:30: @22[35]: _100 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
136+
6:14-6:30: @22.Call: _98 = ArgumentV1::new::&lt;&amp;i32&gt;(move _99, move _100) -&gt; [return: bb23, unwind: bb33]
137+
6:14-6:30: @23[4]: _102 = &amp;(*_97)
138+
6:14-6:30: @23[6]: _103 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
139+
6:14-6:30: @23.Call: _101 = ArgumentV1::new::&lt;&amp;i32&gt;(move _102, move _103) -&gt; [return: bb24, unwind: bb33]
140+
6:14-6:30: @24[2]: _90 = [move _98, move _101]
141+
6:14-6:30: @24[7]: _89 = &amp;_90
142+
6:14-6:30: @24[8]: _88 = &amp;(*_89)
143+
6:14-6:30: @24[9]: _87 = move _88 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
144+
6:14-6:30: @24.Call: _82 = Arguments::new_v1(move _83, move _87) -&gt; [return: bb25, unwind: bb33]
145+
6:14-6:30: @25.Call: core::panicking::panic_fmt(move _82) -&gt; 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>
146+
<span class="line"><span class="code" style="--layer: 0"> _ =&gt; </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]
147+
7:14-7:30: @28[6]: _119 = &amp;(*_147)
148+
7:14-7:30: @28[7]: _118 = &amp;(*_119)
149+
7:14-7:30: @28[8]: _117 = move _118 as &amp;[&amp;str] (Pointer(Unsize))
150+
7:14-7:30: @28[17]: _127 = &amp;(*_109)
151+
7:14-7:30: @28[18]: _126 = &amp;_127
152+
7:14-7:30: @28[21]: _129 = &amp;(*_110)
153+
7:14-7:30: @28[22]: _128 = &amp;_129
154+
7:14-7:30: @28[23]: _125 = (move _126, move _128)
155+
7:14-7:30: @28[26]: FakeRead(ForMatchedPlace, _125)
156+
7:14-7:30: @28[28]: _130 = (_125.0: &amp;&amp;i32)
157+
7:14-7:30: @28[30]: _131 = (_125.1: &amp;&amp;i32)
158+
7:14-7:30: @28[33]: _133 = &amp;(*_130)
159+
7:14-7:30: @28[35]: _134 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
160+
7:14-7:30: @28.Call: _132 = ArgumentV1::new::&lt;&amp;i32&gt;(move _133, move _134) -&gt; [return: bb29, unwind: bb33]
161+
7:14-7:30: @29[4]: _136 = &amp;(*_131)
162+
7:14-7:30: @29[6]: _137 = &lt;&amp;i32 as Debug&gt;::fmt as for&lt;&#39;r, &#39;s, &#39;t0&gt; fn(&amp;&#39;r &amp;i32, &amp;&#39;s mut std::fmt::Formatter&lt;&#39;t0&gt;) -&gt; std::result::Result&lt;(), std::fmt::Error&gt; (Pointer(ReifyFnPointer))
163+
7:14-7:30: @29.Call: _135 = ArgumentV1::new::&lt;&amp;i32&gt;(move _136, move _137) -&gt; [return: bb30, unwind: bb33]
164+
7:14-7:30: @30[2]: _124 = [move _132, move _135]
165+
7:14-7:30: @30[7]: _123 = &amp;_124
166+
7:14-7:30: @30[8]: _122 = &amp;(*_123)
167+
7:14-7:30: @30[9]: _121 = move _122 as &amp;[std::fmt::ArgumentV1] (Pointer(Unsize))
168+
7:14-7:30: @30.Call: _116 = Arguments::new_v1(move _117, move _121) -&gt; [return: bb31, unwind: bb33]
169+
7:14-7:30: @31.Call: core::panicking::panic_fmt(move _116) -&gt; 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>
170+
<span class="line"><span class="code" style="--layer: 0"> }</span></span>
171+
<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>
172+
</body>
173+
</html>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# Directory "instrument-coverage" supports the tests at prefix ../instrument-coverage-*
1+
# Directory "coverage" supports the tests at prefix ../coverage-*
22

3-
# Use ./x.py [options] test src/test/run-make-fulldeps/instrument-coverage to run all related tests.
3+
# Use ./x.py [options] test src/test/run-make-fulldeps/coverage to run all related tests.

‎src/test/run-make-fulldeps/coverage/coverage_tools.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Common Makefile include for Rust `run-make-fulldeps/instrument-coverage-* tests. Include this
1+
# Common Makefile include for Rust `run-make-fulldeps/coverage-* tests. Include this
22
# file with the line:
33
#
4-
# -include ../instrument-coverage/coverage_tools.mk
4+
# -include ../coverage/coverage_tools.mk
55

66
-include ../tools.mk
77

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
//! ```
6+
//! if true {
7+
//! // this is executed!
8+
//! assert_eq!(1, 1);
9+
//! } else {
10+
//! // this is not!
11+
//! assert_eq!(1, 2);
12+
//! }
13+
//! ```
14+
//!
15+
//! doctest testing external code:
16+
//! ```
17+
//! extern crate doctest_crate;
18+
//! doctest_crate::fn_run_in_doctests(1);
19+
//! ```
20+
//!
21+
//! doctest returning a result:
22+
//! ```
23+
//! #[derive(Debug)]
24+
//! struct SomeError;
25+
//! let mut res = Err(SomeError);
26+
//! if res.is_ok() {
27+
//! res?;
28+
//! } else {
29+
//! res = Ok(0);
30+
//! }
31+
//! // need to be explicit because rustdoc cant infer the return type
32+
//! Ok::<(), SomeError>(())
33+
//! ```
34+
//!
35+
//! doctest with custom main:
36+
//! ```
37+
//! #[derive(Debug)]
38+
//! struct SomeError;
39+
//!
40+
//! extern crate doctest_crate;
41+
//!
42+
//! fn doctest_main() -> Result<(), SomeError> {
43+
//! doctest_crate::fn_run_in_doctests(2);
44+
//! Ok(())
45+
//! }
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+
/// extern crate doctest_crate;
57+
/// doctest_crate::fn_run_in_doctests(3);
58+
/// ```
59+
///
60+
fn main() {
61+
if true {
62+
assert_eq!(1, 1);
63+
} else {
64+
assert_eq!(1, 2);
65+
}
66+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// A function run only from within doctests
2+
pub fn fn_run_in_doctests(conditional: usize) {
3+
match conditional {
4+
1 => assert_eq!(1, 1), // this is run,
5+
2 => assert_eq!(1, 1), // this,
6+
3 => assert_eq!(1, 1), // and this too
7+
_ => assert_eq!(1, 2), // however this is not
8+
}
9+
}

0 commit comments

Comments
 (0)
Please sign in to comment.