Skip to content

Commit 7776678

Browse files
Prevent cloning more than necessary RustdocOptions fields
1 parent 6c2e8dc commit 7776678

File tree

1 file changed

+77
-48
lines changed

1 file changed

+77
-48
lines changed

src/librustdoc/doctest.rs

+77-48
Original file line numberDiff line numberDiff line change
@@ -379,34 +379,34 @@ fn run_test(
379379
test: &str,
380380
crate_name: &str,
381381
line: usize,
382-
rustdoc_options: RustdocOptions,
382+
rustdoc_options: RustdocTestOptions,
383383
mut lang_string: LangString,
384384
no_run: bool,
385-
runtool: Option<String>,
386-
runtool_args: Vec<String>,
387-
target: TargetTriple,
388385
opts: &GlobalTestOptions,
389386
edition: Edition,
390-
outdir: DirState,
391387
path: PathBuf,
392-
test_id: &str,
393388
report_unused_externs: impl Fn(UnusedExterns),
394-
arg_file: PathBuf,
395389
) -> Result<(), TestFailure> {
396-
let (test, line_offset, supports_color) =
397-
make_test(test, Some(crate_name), lang_string.test_harness, opts, edition, Some(test_id));
390+
let (test, line_offset, supports_color) = make_test(
391+
test,
392+
Some(crate_name),
393+
lang_string.test_harness,
394+
opts,
395+
edition,
396+
Some(&rustdoc_options.test_id),
397+
);
398398

399399
// Make sure we emit well-formed executable names for our target.
400-
let rust_out = add_exe_suffix("rust_out".to_owned(), &target);
401-
let output_file = outdir.path().join(rust_out);
400+
let rust_out = add_exe_suffix("rust_out".to_owned(), &rustdoc_options.target);
401+
let output_file = rustdoc_options.outdir.path().join(rust_out);
402402

403403
let rustc_binary = rustdoc_options
404404
.test_builder
405405
.as_deref()
406406
.unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
407407
let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
408408

409-
compiler.arg(&format!("@{}", arg_file.display()));
409+
compiler.arg(&format!("@{}", rustdoc_options.arg_file.display()));
410410

411411
compiler.arg("--edition").arg(&edition.to_string());
412412
compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", path);
@@ -415,17 +415,17 @@ fn run_test(
415415
if lang_string.test_harness {
416416
compiler.arg("--test");
417417
}
418-
if rustdoc_options.json_unused_externs.is_enabled() && !lang_string.compile_fail {
418+
if rustdoc_options.is_json_unused_externs_enabled && !lang_string.compile_fail {
419419
compiler.arg("--error-format=json");
420420
compiler.arg("--json").arg("unused-externs");
421421
compiler.arg("-W").arg("unused_crate_dependencies");
422422
compiler.arg("-Z").arg("unstable-options");
423423
}
424424

425-
if no_run && !lang_string.compile_fail && rustdoc_options.persist_doctests.is_none() {
425+
if no_run && !lang_string.compile_fail && rustdoc_options.should_persist_doctests {
426426
compiler.arg("--emit=metadata");
427427
}
428-
compiler.arg("--target").arg(match target {
428+
compiler.arg("--target").arg(match rustdoc_options.target {
429429
TargetTriple::TargetTriple(s) => s,
430430
TargetTriple::TargetJson { path_for_rustdoc, .. } => {
431431
path_for_rustdoc.to_str().expect("target path must be valid unicode").to_string()
@@ -521,10 +521,10 @@ fn run_test(
521521
let mut cmd;
522522

523523
let output_file = make_maybe_absolute_path(output_file);
524-
if let Some(tool) = runtool {
524+
if let Some(tool) = rustdoc_options.runtool {
525525
let tool = make_maybe_absolute_path(tool.into());
526526
cmd = Command::new(tool);
527-
cmd.args(runtool_args);
527+
cmd.args(rustdoc_options.runtool_args);
528528
cmd.arg(output_file);
529529
} else {
530530
cmd = Command::new(output_file);
@@ -933,6 +933,61 @@ fn partition_source(s: &str, edition: Edition) -> (String, String, String) {
933933
(before, after, crates)
934934
}
935935

936+
pub(crate) struct RustdocTestOptions {
937+
test_builder: Option<PathBuf>,
938+
test_builder_wrappers: Vec<PathBuf>,
939+
is_json_unused_externs_enabled: bool,
940+
should_persist_doctests: bool,
941+
error_format: ErrorOutputType,
942+
test_run_directory: Option<PathBuf>,
943+
nocapture: bool,
944+
arg_file: PathBuf,
945+
outdir: DirState,
946+
runtool: Option<String>,
947+
runtool_args: Vec<String>,
948+
target: TargetTriple,
949+
test_id: String,
950+
}
951+
952+
impl RustdocTestOptions {
953+
fn new(options: &RustdocOptions, arg_file: &Path, test_id: String) -> Self {
954+
let outdir = if let Some(ref path) = options.persist_doctests {
955+
let mut path = path.clone();
956+
path.push(&test_id);
957+
958+
if let Err(err) = std::fs::create_dir_all(&path) {
959+
eprintln!("Couldn't create directory for doctest executables: {err}");
960+
panic::resume_unwind(Box::new(()));
961+
}
962+
963+
DirState::Perm(path)
964+
} else {
965+
DirState::Temp(
966+
TempFileBuilder::new()
967+
.prefix("rustdoctest")
968+
.tempdir()
969+
.expect("rustdoc needs a tempdir"),
970+
)
971+
};
972+
973+
Self {
974+
test_builder: options.test_builder.clone(),
975+
test_builder_wrappers: options.test_builder_wrappers.clone(),
976+
is_json_unused_externs_enabled: options.json_unused_externs.is_enabled(),
977+
should_persist_doctests: options.persist_doctests.is_none(),
978+
error_format: options.error_format,
979+
test_run_directory: options.test_run_directory.clone(),
980+
nocapture: options.nocapture,
981+
arg_file: arg_file.into(),
982+
outdir,
983+
runtool: options.runtool.clone(),
984+
runtool_args: options.runtool_args.clone(),
985+
target: options.target.clone(),
986+
test_id,
987+
}
988+
}
989+
}
990+
936991
pub(crate) trait Tester {
937992
fn add_test(&mut self, test: String, config: LangString, line: usize);
938993
fn get_line(&self) -> usize {
@@ -1048,13 +1103,9 @@ impl Tester for Collector {
10481103
let crate_name = self.crate_name.clone();
10491104
let opts = self.opts.clone();
10501105
let edition = config.edition.unwrap_or(self.rustdoc_options.edition);
1051-
let rustdoc_options = self.rustdoc_options.clone();
1052-
let runtool = self.rustdoc_options.runtool.clone();
1053-
let runtool_args = self.rustdoc_options.runtool_args.clone();
1054-
let target = self.rustdoc_options.target.clone();
1055-
let target_str = target.to_string();
1106+
let target_str = self.rustdoc_options.target.to_string();
10561107
let unused_externs = self.unused_extern_reports.clone();
1057-
let no_run = config.no_run || rustdoc_options.no_run;
1108+
let no_run = config.no_run || self.rustdoc_options.no_run;
10581109
if !config.compile_fail {
10591110
self.compiling_test_count.fetch_add(1, Ordering::SeqCst);
10601111
}
@@ -1088,25 +1139,9 @@ impl Tester for Collector {
10881139
self.visited_tests.entry((file.clone(), line)).and_modify(|v| *v += 1).or_insert(0)
10891140
},
10901141
);
1091-
let outdir = if let Some(mut path) = rustdoc_options.persist_doctests.clone() {
1092-
path.push(&test_id);
1093-
1094-
if let Err(err) = std::fs::create_dir_all(&path) {
1095-
eprintln!("Couldn't create directory for doctest executables: {err}");
1096-
panic::resume_unwind(Box::new(()));
1097-
}
1098-
1099-
DirState::Perm(path)
1100-
} else {
1101-
DirState::Temp(
1102-
TempFileBuilder::new()
1103-
.prefix("rustdoctest")
1104-
.tempdir()
1105-
.expect("rustdoc needs a tempdir"),
1106-
)
1107-
};
11081142

1109-
let arg_file = self.arg_file.clone();
1143+
let rustdoc_test_options =
1144+
RustdocTestOptions::new(&self.rustdoc_options, &self.arg_file, test_id);
11101145

11111146
debug!("creating test {name}: {test}");
11121147
self.tests.push(test::TestDescAndFn {
@@ -1137,19 +1172,13 @@ impl Tester for Collector {
11371172
&test,
11381173
&crate_name,
11391174
line,
1140-
rustdoc_options,
1175+
rustdoc_test_options,
11411176
config,
11421177
no_run,
1143-
runtool,
1144-
runtool_args,
1145-
target,
11461178
&opts,
11471179
edition,
1148-
outdir,
11491180
path,
1150-
&test_id,
11511181
report_unused_externs,
1152-
arg_file,
11531182
);
11541183

11551184
if let Err(err) = res {

0 commit comments

Comments
 (0)