Skip to content

Commit 84b6025

Browse files
Rollup merge of #144805 - Zalathar:proc-res, r=jieyouxu
compiletest: Preliminary cleanup of `ProcRes` printing/unwinding While experimenting with changes to how compiletest handles output capture, error reporting, and unwinding, I repeatedly ran in to difficulties with this core code for reporting test failures caused by a subprocess. There should be no change in compiletest output. r? jieyouxu
2 parents c6d3a55 + 1063b0f commit 84b6025

3 files changed

Lines changed: 56 additions & 45 deletions

File tree

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,10 @@ impl<'test> TestCx<'test> {
354354
}
355355
}else{
356356
if proc_res.status.success(){
357-
{
358-
self.error(&format!("{} test did not emit an error",self.config.mode));
359-
ifself.config.mode == crate::common::TestMode::Ui{
360-
println!("note: by default, ui tests are expected not to compile");
361-
}
362-
proc_res.fatal(None, || ());
363-
};
357+
let err = &format!("{} test did not emit an error",self.config.mode);
358+
let extra_note = (self.config.mode == crate::common::TestMode::Ui)
359+
.then_some("note: by default, ui tests are expected not to compile");
360+
self.fatal_proc_rec_general(err, extra_note, proc_res, || ());
364361
}
365362

366363
if !self.props.dont_check_failure_status{
@@ -606,7 +603,10 @@ impl<'test> TestCx<'test> {
606603
);
607604
}else{
608605
for pattern in missing_patterns {
609-
self.error(&format!("error pattern '{}' not found!", pattern));
606+
println!(
607+
"\n{prefix}: error pattern '{pattern}' not found!",
608+
prefix = self.error_prefix()
609+
);
610610
}
611611
self.fatal_proc_rec("multiple error patterns not found", proc_res);
612612
}
@@ -824,10 +824,11 @@ impl<'test> TestCx<'test> {
824824
// - only known line - meh, but suggested
825825
// - others are not worth suggesting
826826
if !unexpected.is_empty(){
827-
self.error(&format!(
828-
"{} diagnostics reported in JSON output but not expected in test file",
829-
unexpected.len(),
830-
));
827+
println!(
828+
"\n{prefix}: {n} diagnostics reported in JSON output but not expected in test file",
829+
prefix = self.error_prefix(),
830+
n = unexpected.len(),
831+
);
831832
for error in&unexpected {
832833
print_error(error);
833834
letmut suggestions = Vec::new();
@@ -857,10 +858,11 @@ impl<'test> TestCx<'test> {
857858
}
858859
}
859860
if !not_found.is_empty(){
860-
self.error(&format!(
861-
"{} diagnostics expected in test file but not reported in JSON output",
862-
not_found.len()
863-
));
861+
println!(
862+
"\n{prefix}: {n} diagnostics expected in test file but not reported in JSON output",
863+
prefix = self.error_prefix(),
864+
n = not_found.len(),
865+
);
864866
for error in&not_found {
865867
print_error(error);
866868
letmut suggestions = Vec::new();
@@ -1995,33 +1997,52 @@ impl<'test> TestCx<'test> {
19951997
output_base_name(self.config,self.testpaths,self.safe_revision())
19961998
}
19971999

1998-
fnerror(&self,err:&str){
2000+
/// Prefix to print before error messages. Normally just `error`, but also
2001+
/// includes the revision name for tests that use revisions.
2002+
#[must_use]
2003+
fnerror_prefix(&self) -> String{
19992004
matchself.revision{
2000-
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
2001-
None => println!("\nerror: {}", err),
2005+
Some(rev) => format!("error in revision `{rev}`"),
2006+
None => format!("error"),
20022007
}
20032008
}
20042009

20052010
#[track_caller]
20062011
fnfatal(&self,err:&str) -> ! {
2007-
self.error(err);
2012+
println!("\n{prefix}: {err}", prefix = self.error_prefix());
20082013
error!("fatal error, panic: {:?}", err);
20092014
panic!("fatal error");
20102015
}
20112016

20122017
fnfatal_proc_rec(&self,err:&str,proc_res:&ProcRes) -> ! {
2013-
self.error(err);
2014-
proc_res.fatal(None, || ());
2018+
self.fatal_proc_rec_general(err,None, proc_res, || ());
20152019
}
20162020

2017-
fnfatal_proc_rec_with_ctx(
2021+
/// Underlying implementation of [`Self::fatal_proc_rec`], providing some
2022+
/// extra capabilities not needed by most callers.
2023+
fnfatal_proc_rec_general(
20182024
&self,
20192025
err:&str,
2026+
extra_note:Option<&str>,
20202027
proc_res:&ProcRes,
2021-
on_failure:implFnOnce(Self),
2028+
callback_before_unwind:implFnOnce(),
20222029
) -> ! {
2023-
self.error(err);
2024-
proc_res.fatal(None, || on_failure(*self));
2030+
println!("\n{prefix}: {err}", prefix = self.error_prefix());
2031+
2032+
// Some callers want to print additional notes after the main error message.
2033+
ifletSome(note) = extra_note {
2034+
println!("{note}");
2035+
}
2036+
2037+
// Print the details and output of the subprocess that caused this test to fail.
2038+
println!("{}", proc_res.format_info());
2039+
2040+
// Some callers want print more context or show a custom diff before the unwind occurs.
2041+
callback_before_unwind();
2042+
2043+
// Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
2044+
// compiletest, which is unnecessary noise.
2045+
std::panic::resume_unwind(Box::new(()));
20252046
}
20262047

20272048
// codegen tests (using FileCheck)
@@ -2080,7 +2101,7 @@ impl<'test> TestCx<'test> {
20802101
ifcfg!(target_os = "freebsd"){"ISO-8859-1"}else{"UTF-8"}
20812102
}
20822103

2083-
fncompare_to_default_rustdoc(&mutself,out_dir:&Utf8Path){
2104+
fncompare_to_default_rustdoc(&self,out_dir:&Utf8Path){
20842105
if !self.config.has_html_tidy{
20852106
return;
20862107
}
@@ -2957,7 +2978,8 @@ pub struct ProcRes {
29572978
}
29582979

29592980
implProcRes{
2960-
pubfnprint_info(&self){
2981+
#[must_use]
2982+
pubfnformat_info(&self) -> String{
29612983
fnrender(name:&str,contents:&str) -> String{
29622984
let contents = json::extract_rendered(contents);
29632985
let contents = contents.trim_end();
@@ -2973,24 +2995,13 @@ impl ProcRes {
29732995
}
29742996
}
29752997

2976-
println!(
2998+
format!(
29772999
"status: {}\ncommand: {}\n{}\n{}\n",
29783000
self.status,
29793001
self.cmdline,
29803002
render("stdout",&self.stdout),
29813003
render("stderr",&self.stderr),
2982-
);
2983-
}
2984-
2985-
pubfnfatal(&self,err:Option<&str>,on_failure:implFnOnce()) -> ! {
2986-
ifletSome(e) = err {
2987-
println!("\nerror: {}", e);
2988-
}
2989-
self.print_info();
2990-
on_failure();
2991-
// Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
2992-
// compiletest, which is unnecessary noise.
2993-
std::panic::resume_unwind(Box::new(()));
3004+
)
29943005
}
29953006
}
29963007

‎src/tools/compiletest/src/runtest/rustdoc.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ impl TestCx<'_> {
2828
}
2929
let res = self.run_command_to_procres(&mut cmd);
3030
if !res.status.success(){
31-
self.fatal_proc_rec_with_ctx("htmldocck failed!",&res, |mut this| {
32-
this.compare_to_default_rustdoc(&out_dir)
31+
self.fatal_proc_rec_general("htmldocck failed!",None,&res, || {
32+
self.compare_to_default_rustdoc(&out_dir);
3333
});
3434
}
3535
}

‎src/tools/compiletest/src/runtest/rustdoc_json.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ impl TestCx<'_> {
2929
);
3030

3131
if !res.status.success(){
32-
self.fatal_proc_rec_with_ctx("jsondocck failed!",&res, |_| {
32+
self.fatal_proc_rec_general("jsondocck failed!",None,&res, || {
3333
println!("Rustdoc Output:");
34-
proc_res.print_info();
34+
println!("{}",proc_res.format_info());
3535
})
3636
}
3737

0 commit comments

Comments
 (0)