mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #138281 - saethlin:mergeable-doctests-stacksize, r=GuillaumeGomez
Fix O(tests) stack usage in edition 2024 mergeable doctests Fixes https://github.com/rust-lang/rust/issues/138248 The important change here is that we are not passing a potentially-large array by value. Between the fact that `TestFn` cannot be `Clone` and `test_main` takes a `Vec<TestDescAndFn>`, the only way to call `test::test_main` without O(tests) stack use is to call `Vec::push` many times. The normal test harness does not have this problem because it calls `test_main_static` or `test_main_static_abort`, which take `&[TestDescAndFn]`. Changing `test::test_main` to take a slice is not a simple change, so I'm avoiding doing it here.
This commit is contained in:
commit
d1a875cd37
@ -47,11 +47,8 @@ impl DocTestRunner {
|
|||||||
self.crate_attrs.insert(line.to_string());
|
self.crate_attrs.insert(line.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.ids.is_empty() {
|
|
||||||
self.ids.push(',');
|
|
||||||
}
|
|
||||||
self.ids.push_str(&format!(
|
self.ids.push_str(&format!(
|
||||||
"{}::TEST",
|
"tests.push({}::TEST);\n",
|
||||||
generate_mergeable_doctest(
|
generate_mergeable_doctest(
|
||||||
doctest,
|
doctest,
|
||||||
scraped_test,
|
scraped_test,
|
||||||
@ -142,7 +139,11 @@ mod __doctest_mod {{
|
|||||||
|
|
||||||
#[rustc_main]
|
#[rustc_main]
|
||||||
fn main() -> std::process::ExitCode {{
|
fn main() -> std::process::ExitCode {{
|
||||||
const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}];
|
let tests = {{
|
||||||
|
let mut tests = Vec::with_capacity({nb_tests});
|
||||||
|
{ids}
|
||||||
|
tests
|
||||||
|
}};
|
||||||
let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION);
|
let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION);
|
||||||
let test_args = &[{test_args}];
|
let test_args = &[{test_args}];
|
||||||
const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
|
const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
|
||||||
@ -150,11 +151,11 @@ const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\";
|
|||||||
if let Ok(binary) = std::env::var(ENV_BIN) {{
|
if let Ok(binary) = std::env::var(ENV_BIN) {{
|
||||||
let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into());
|
let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into());
|
||||||
unsafe {{ std::env::remove_var(ENV_BIN); }}
|
unsafe {{ std::env::remove_var(ENV_BIN); }}
|
||||||
return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None));
|
return std::process::Termination::report(test::test_main(test_args, tests, None));
|
||||||
}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{
|
}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{
|
||||||
if let Ok(nb_test) = nb_test.parse::<usize>() {{
|
if let Ok(nb_test) = nb_test.parse::<usize>() {{
|
||||||
if let Some(test) = TESTS.get(nb_test) {{
|
if let Some(test) = tests.get(nb_test) {{
|
||||||
if let test::StaticTestFn(f) = test.testfn {{
|
if let test::StaticTestFn(f) = &test.testfn {{
|
||||||
return std::process::Termination::report(f());
|
return std::process::Termination::report(f());
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
@ -164,7 +165,7 @@ if let Ok(binary) = std::env::var(ENV_BIN) {{
|
|||||||
|
|
||||||
eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \
|
eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \
|
||||||
the same process\");
|
the same process\");
|
||||||
std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None))
|
std::process::Termination::report(test::test_main(test_args, tests, None))
|
||||||
}}",
|
}}",
|
||||||
nb_tests = self.nb_tests,
|
nb_tests = self.nb_tests,
|
||||||
output = self.output_merged_tests,
|
output = self.output_merged_tests,
|
||||||
|
Loading…
Reference in New Issue
Block a user