Skip to content

Commit 3e31006

Browse files
authored
Rollup merge of #69458 - Luro02:master, r=GuillaumeGomez,ollie27
improve folder name for persistent doc tests This fixes #69411, by using the entire path as folder name and storing already visited paths in a HashMap + appending a number to the file name for duplicates.
2 parents f62cfa7 + 2e40ac7 commit 3e31006

File tree

1 file changed

+63
-40
lines changed

1 file changed

+63
-40
lines changed

src/librustdoc/test.rs

+63-40
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_span::source_map::SourceMap;
1313
use rustc_span::symbol::sym;
1414
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
1515
use rustc_target::spec::TargetTriple;
16+
use std::collections::HashMap;
1617
use std::env;
1718
use std::io::{self, Write};
1819
use std::panic;
@@ -190,10 +191,23 @@ enum TestFailure {
190191
UnexpectedRunPass,
191192
}
192193

194+
enum DirState {
195+
Temp(tempfile::TempDir),
196+
Perm(PathBuf),
197+
}
198+
199+
impl DirState {
200+
fn path(&self) -> &std::path::Path {
201+
match self {
202+
DirState::Temp(t) => t.path(),
203+
DirState::Perm(p) => p.as_path(),
204+
}
205+
}
206+
}
207+
193208
fn run_test(
194209
test: &str,
195210
cratename: &str,
196-
filename: &FileName,
197211
line: usize,
198212
options: Options,
199213
should_panic: bool,
@@ -206,47 +220,11 @@ fn run_test(
206220
mut error_codes: Vec<String>,
207221
opts: &TestOptions,
208222
edition: Edition,
223+
outdir: DirState,
224+
path: PathBuf,
209225
) -> Result<(), TestFailure> {
210226
let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts, edition);
211227

212-
// FIXME(#44940): if doctests ever support path remapping, then this filename
213-
// needs to be the result of `SourceMap::span_to_unmapped_path`.
214-
let path = match filename {
215-
FileName::Real(path) => path.clone(),
216-
_ => PathBuf::from(r"doctest.rs"),
217-
};
218-
219-
enum DirState {
220-
Temp(tempfile::TempDir),
221-
Perm(PathBuf),
222-
}
223-
224-
impl DirState {
225-
fn path(&self) -> &std::path::Path {
226-
match self {
227-
DirState::Temp(t) => t.path(),
228-
DirState::Perm(p) => p.as_path(),
229-
}
230-
}
231-
}
232-
233-
let outdir = if let Some(mut path) = options.persist_doctests {
234-
path.push(format!(
235-
"{}_{}",
236-
filename.to_string().rsplit('/').next().unwrap().replace(".", "_"),
237-
line
238-
));
239-
std::fs::create_dir_all(&path).expect("Couldn't create directory for doctest executables");
240-
241-
DirState::Perm(path)
242-
} else {
243-
DirState::Temp(
244-
TempFileBuilder::new()
245-
.prefix("rustdoctest")
246-
.tempdir()
247-
.expect("rustdoc needs a tempdir"),
248-
)
249-
};
250228
let output_file = outdir.path().join("rust_out");
251229

252230
let rustc_binary = options
@@ -639,6 +617,7 @@ pub struct Collector {
639617
position: Span,
640618
source_map: Option<Lrc<SourceMap>>,
641619
filename: Option<PathBuf>,
620+
visited_tests: HashMap<(String, usize), usize>,
642621
}
643622

644623
impl Collector {
@@ -662,6 +641,7 @@ impl Collector {
662641
position: DUMMY_SP,
663642
source_map,
664643
filename,
644+
visited_tests: HashMap::new(),
665645
}
666646
}
667647

@@ -705,6 +685,48 @@ impl Tester for Collector {
705685
let target = self.options.target.clone();
706686
let target_str = target.to_string();
707687

688+
// FIXME(#44940): if doctests ever support path remapping, then this filename
689+
// needs to be the result of `SourceMap::span_to_unmapped_path`.
690+
let path = match &filename {
691+
FileName::Real(path) => path.clone(),
692+
_ => PathBuf::from(r"doctest.rs"),
693+
};
694+
695+
let outdir = if let Some(mut path) = options.persist_doctests.clone() {
696+
// For example `module/file.rs` would become `module_file_rs`
697+
let folder_name = filename
698+
.to_string()
699+
.chars()
700+
.map(|c| if c == '/' || c == '.' { '_' } else { c })
701+
.collect::<String>();
702+
703+
path.push(format!(
704+
"{name}_{line}_{number}",
705+
name = folder_name,
706+
number = {
707+
// Increases the current test number, if this file already
708+
// exists or it creates a new entry with a test number of 0.
709+
self.visited_tests
710+
.entry((folder_name.clone(), line))
711+
.and_modify(|v| *v += 1)
712+
.or_insert(0)
713+
},
714+
line = line,
715+
));
716+
717+
std::fs::create_dir_all(&path)
718+
.expect("Couldn't create directory for doctest executables");
719+
720+
DirState::Perm(path)
721+
} else {
722+
DirState::Temp(
723+
TempFileBuilder::new()
724+
.prefix("rustdoctest")
725+
.tempdir()
726+
.expect("rustdoc needs a tempdir"),
727+
)
728+
};
729+
708730
debug!("creating test {}: {}", name, test);
709731
self.tests.push(testing::TestDescAndFn {
710732
desc: testing::TestDesc {
@@ -723,7 +745,6 @@ impl Tester for Collector {
723745
let res = run_test(
724746
&test,
725747
&cratename,
726-
&filename,
727748
line,
728749
options,
729750
config.should_panic,
@@ -736,6 +757,8 @@ impl Tester for Collector {
736757
config.error_codes,
737758
&opts,
738759
edition,
760+
outdir,
761+
path,
739762
);
740763

741764
if let Err(err) = res {

0 commit comments

Comments
 (0)