@@ -39,6 +39,7 @@ impl DocTestRunner {
3939        doctest :  & DocTestBuilder , 
4040        scraped_test :  & ScrapedDocTest , 
4141        target_str :  & str , 
42+         opts :  & RustdocOptions , 
4243    )  { 
4344        let  ignore = match  scraped_test. langstr . ignore  { 
4445            Ignore :: All  => true , 
@@ -62,6 +63,7 @@ impl DocTestRunner {
6263                self . nb_tests, 
6364                & mut  self . output, 
6465                & mut  self . output_merged_tests, 
66+                 opts, 
6567            ) , 
6668        ) ) ; 
6769        self . supports_color  &= doctest. supports_color ; 
@@ -127,20 +129,30 @@ mod __doctest_mod {{
127129
128130    pub static BINARY_PATH: OnceLock<PathBuf> = OnceLock::new(); 
129131    pub const RUN_OPTION: &str = \" RUSTDOC_DOCTEST_RUN_NB_TEST\" ; 
132+     pub const SHOULD_PANIC_DISABLED: bool = ( 
133+         cfg!(target_family = \" wasm\" ) || cfg!(target_os = \" zkvm\" ) 
134+     ) && !cfg!(target_os = \" emscripten\" ); 
130135
131136    #[allow(unused)] 
132137    pub fn doctest_path() -> Option<&'static PathBuf> {{ 
133138        self::BINARY_PATH.get() 
134139    }} 
135140
136141    #[allow(unused)] 
137-     pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> ExitCode {{ 
142+     pub fn doctest_runner(bin: &std::path::Path, test_nb: usize, should_panic: bool ) -> ExitCode {{ 
138143        let out = std::process::Command::new(bin) 
139144            .env(self::RUN_OPTION, test_nb.to_string()) 
140145            .args(std::env::args().skip(1).collect::<Vec<_>>()) 
141146            .output() 
142147            .expect(\" failed to run command\" ); 
143-         if !out.status.success() {{ 
148+         if should_panic {{ 
149+             if out.status.code() != Some(test::ERROR_EXIT_CODE) {{ 
150+                 eprintln!(\" Test didn't panic, but it's marked `should_panic`.\" ); 
151+                 ExitCode::FAILURE 
152+             }} else {{ 
153+                 ExitCode::SUCCESS 
154+             }} 
155+         }} else if !out.status.success() {{ 
144156            if let Some(code) = out.status.code() {{ 
145157                eprintln!(\" Test executable failed (exit status: {{code}}).\" ); 
146158            }} else {{ 
@@ -223,6 +235,7 @@ fn generate_mergeable_doctest(
223235    id :  usize , 
224236    output :  & mut  String , 
225237    output_merged_tests :  & mut  String , 
238+     opts :  & RustdocOptions , 
226239)  -> String  { 
227240    let  test_id = format ! ( "__doctest_{id}" ) ; 
228241
@@ -256,31 +269,33 @@ fn main() {returns_result} {{
256269        ) 
257270        . unwrap ( ) ; 
258271    } 
259-     let  not_running = ignore || scraped_test. langstr . no_run ; 
272+     let  should_panic = scraped_test. langstr . should_panic ; 
273+     let  not_running = ignore || scraped_test. no_run ( opts) ; 
260274    writeln ! ( 
261275        output_merged_tests, 
262276        " 
263277mod {test_id} {{ 
264278pub const TEST: test::TestDescAndFn = test::TestDescAndFn::new_doctest( 
265- {test_name:?}, {ignore}, {file:?}, {line}, {no_run}, {should_panic} , 
279+ {test_name:?}, {ignore} || ({should_panic} && crate::__doctest_mod::SHOULD_PANIC_DISABLED) , {file:?}, {line}, {no_run}, false , 
266280test::StaticTestFn( 
267281    || {{{runner}}}, 
268282)); 
269283}}" , 
270284        test_name = scraped_test. name, 
271285        file = scraped_test. path( ) , 
272286        line = scraped_test. line, 
273-         no_run = scraped_test. langstr. no_run, 
274-         should_panic = !scraped_test. langstr. no_run && scraped_test. langstr. should_panic, 
287+         no_run = scraped_test. no_run( opts) , 
275288        // Setting `no_run` to `true` in `TestDesc` still makes the test run, so we simply 
276289        // don't give it the function to run. 
277290        runner = if  not_running { 
278291            "test::assert_test_result(Ok::<(), String>(()))" . to_string( ) 
279292        }  else { 
280293            format!( 
281294                " 
282- if let Some(bin_path) = crate::__doctest_mod::doctest_path() {{ 
283-     test::assert_test_result(crate::__doctest_mod::doctest_runner(bin_path, {id})) 
295+ if {should_panic} && crate::__doctest_mod::SHOULD_PANIC_DISABLED {{ 
296+     test::assert_test_result(Ok::<(), String>(())) 
297+ }} else if let Some(bin_path) = crate::__doctest_mod::doctest_path() {{ 
298+     test::assert_test_result(crate::__doctest_mod::doctest_runner(bin_path, {id}, {should_panic})) 
284299}} else {{ 
285300    test::assert_test_result(doctest_bundle::{test_id}::__main_fn()) 
286301}} 
0 commit comments