Skip to content

Commit d8fee19

Browse files
Run doctests via out-of-process rustc
This is a work-in-progress.
1 parent cf67ac1 commit d8fee19

File tree

1 file changed

+81
-75
lines changed

1 file changed

+81
-75
lines changed

src/librustdoc/test.rs

Lines changed: 81 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -217,30 +217,30 @@ fn run_test(
217217
_ => PathBuf::from(r"doctest.rs"),
218218
};
219219

220-
let input = config::Input::Str {
221-
name: FileName::DocTest(path, line as isize - line_offset as isize),
222-
input: test,
223-
};
224-
let outputs = OutputTypes::new(&[(OutputType::Exe, None)]);
225-
226-
let sessopts = config::Options {
227-
maybe_sysroot,
228-
search_paths: libs,
229-
crate_types: vec![config::CrateType::Executable],
230-
output_types: outputs,
231-
externs,
232-
cg: config::CodegenOptions {
233-
linker,
234-
..cg
235-
},
236-
test: as_test_harness,
237-
unstable_features: UnstableFeatures::from_environment(),
238-
debugging_opts: config::DebuggingOptions {
239-
..config::basic_debugging_options()
240-
},
241-
edition,
242-
..config::Options::default()
243-
};
220+
//let input = config::Input::Str {
221+
// name: FileName::DocTest(path, line as isize - line_offset as isize),
222+
// input: test,
223+
//};
224+
//let outputs = OutputTypes::new(&[(OutputType::Exe, None)]);
225+
226+
//let sessopts = config::Options {
227+
// maybe_sysroot,
228+
// search_paths: libs,
229+
// crate_types: vec![config::CrateType::Executable],
230+
// output_types: outputs,
231+
// externs,
232+
// cg: config::CodegenOptions {
233+
// linker,
234+
// ..cg
235+
// },
236+
// test: as_test_harness,
237+
// unstable_features: UnstableFeatures::from_environment(),
238+
// debugging_opts: config::DebuggingOptions {
239+
// ..config::basic_debugging_options()
240+
// },
241+
// edition,
242+
// ..config::Options::default()
243+
//};
244244

245245
// Shuffle around a few input and output handles here. We're going to pass
246246
// an explicit handle into rustc to collect output messages, but we also
@@ -252,25 +252,25 @@ fn run_test(
252252
//
253253
// The basic idea is to not use a default Handler for rustc, and then also
254254
// not print things by default to the actual stderr.
255-
struct Sink(Arc<Mutex<Vec<u8>>>);
256-
impl Write for Sink {
257-
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
258-
Write::write(&mut *self.0.lock().unwrap(), data)
259-
}
260-
fn flush(&mut self) -> io::Result<()> { Ok(()) }
261-
}
262-
struct Bomb(Arc<Mutex<Vec<u8>>>, Option<Box<dyn Write+Send>>);
263-
impl Drop for Bomb {
264-
fn drop(&mut self) {
265-
let mut old = self.1.take().unwrap();
266-
let _ = old.write_all(&self.0.lock().unwrap());
267-
io::set_panic(Some(old));
268-
}
269-
}
270-
let data = Arc::new(Mutex::new(Vec::new()));
271-
272-
let old = io::set_panic(Some(box Sink(data.clone())));
273-
let _bomb = Bomb(data.clone(), Some(old.unwrap_or(box io::stdout())));
255+
//struct Sink(Arc<Mutex<Vec<u8>>>);
256+
//impl Write for Sink {
257+
// fn write(&mut self, data: &[u8]) -> io::Result<usize> {
258+
// Write::write(&mut *self.0.lock().unwrap(), data)
259+
// }
260+
// fn flush(&mut self) -> io::Result<()> { Ok(()) }
261+
//}
262+
//struct Bomb(Arc<Mutex<Vec<u8>>>, Option<Box<dyn Write+Send>>);
263+
//impl Drop for Bomb {
264+
// fn drop(&mut self) {
265+
// let mut old = self.1.take().unwrap();
266+
// let _ = old.write_all(&self.0.lock().unwrap());
267+
// io::set_panic(Some(old));
268+
// }
269+
//}
270+
//let data = Arc::new(Mutex::new(Vec::new()));
271+
272+
//let old = io::set_panic(Some(box Sink(data.clone())));
273+
//let _bomb = Bomb(data.clone(), Some(old.unwrap_or(box io::stdout())));
274274

275275
enum DirState {
276276
Temp(tempfile::TempDir),
@@ -308,49 +308,55 @@ fn run_test(
308308
};
309309
let output_file = outdir.path().join("rust_out");
310310

311-
let config = interface::Config {
312-
opts: sessopts,
313-
crate_cfg: config::parse_cfgspecs(cfgs),
314-
input,
315-
input_path: None,
316-
output_file: Some(output_file.clone()),
317-
output_dir: None,
318-
file_loader: None,
319-
diagnostic_output: DiagnosticOutput::Raw(box Sink(data.clone())),
320-
stderr: Some(data.clone()),
321-
crate_name: None,
322-
lint_caps: Default::default(),
323-
};
324-
325-
let compile_result = panic::catch_unwind(AssertUnwindSafe(|| {
326-
interface::run_compiler(config, |compiler| {
327-
if no_run {
328-
compiler.global_ctxt().and_then(|global_ctxt| global_ctxt.take().enter(|tcx| {
329-
tcx.analysis(LOCAL_CRATE)
330-
})).ok();
331-
} else {
332-
compiler.compile().ok();
333-
};
334-
compiler.session().compile_status()
335-
})
336-
})).map_err(|_| ()).and_then(|s| s.map_err(|_| ()));
311+
let input_file = outdir.path().join("input.rs");
312+
std::fs::write(&input_file, test).expect("could write out test sources");
337313

338-
match (compile_result, compile_fail) {
339-
(Ok(()), true) => {
314+
let mut compiler = Command::new(std::env::current_exe().unwrap().with_file_name("rustc"));
315+
for cfg in &cfgs {
316+
compiler.arg("--cfg").arg(&cfg);
317+
}
318+
if let Some(sysroot) = maybe_sysroot {
319+
compiler.arg("--sysroot").arg(sysroot);
320+
}
321+
compiler.arg("--edition").arg(&edition.to_string());
322+
compiler.arg(input_file).current_dir(outdir.path());
323+
compiler.arg("-o").arg(&output_file);
324+
325+
//let config = interface::Config {
326+
// opts: sessopts,
327+
// crate_cfg: config::parse_cfgspecs(cfgs),
328+
// input,
329+
// input_path: None,
330+
// output_file: Some(output_file.clone()),
331+
// output_dir: None,
332+
// file_loader: None,
333+
// diagnostic_output: DiagnosticOutput::Raw(box Sink(data.clone())),
334+
// stderr: Some(data.clone()),
335+
// crate_name: None,
336+
// lint_caps: Default::default(),
337+
//};
338+
339+
let cmd = format!("{:?}", compiler);
340+
let output = compiler.output().unwrap();
341+
342+
match (output.status.success(), compile_fail) {
343+
(true, true) => {
340344
return Err(TestFailure::UnexpectedCompilePass);
341345
}
342-
(Ok(()), false) => {}
343-
(Err(_), true) => {
346+
(true, false) => {}
347+
(false, true) => {
344348
if !error_codes.is_empty() {
345-
let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
349+
let out = String::from_utf8(output.stderr).unwrap();
346350
error_codes.retain(|err| !out.contains(err));
347351

348352
if !error_codes.is_empty() {
349353
return Err(TestFailure::MissingErrorCodes(error_codes));
350354
}
351355
}
352356
}
353-
(Err(_), false) => {
357+
(false, false) => {
358+
eprintln!("{}", cmd);
359+
eprintln!("{:?}", output);
354360
return Err(TestFailure::CompileError);
355361
}
356362
}

0 commit comments

Comments
 (0)