Skip to content

Commit 6e8f92f

Browse files
authored
Auto merge of #36981 - alexcrichton:catch-unwind-for-tests, r=sfackler
std: Minor cleanup to libtest * Don't spawn two threads for all tests, just one now that `catch_unwind` is stable. * Remove usage of the unstable `box` keyword * Remove usage of the unstable `FnBox` trait
2 parents ca76c7e + 0714024 commit 6e8f92f

File tree

3 files changed

+67
-67
lines changed

3 files changed

+67
-67
lines changed

src/librustdoc/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ impl Collector {
443443
// compiler failures are test failures
444444
should_panic: testing::ShouldPanic::No,
445445
},
446-
testfn: testing::DynTestFn(box move|| {
446+
testfn: testing::DynTestFn(box move |()| {
447447
runtest(&test,
448448
&cratename,
449449
cfgs,

src/libtest/lib.rs

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
#![cfg_attr(not(stage0), deny(warnings))]
3535

3636
#![feature(asm)]
37-
#![feature(box_syntax)]
38-
#![feature(fnbox)]
3937
#![feature(libc)]
4038
#![feature(rustc_private)]
4139
#![feature(set_stdio)]
@@ -56,8 +54,7 @@ use self::TestEvent::*;
5654
use self::NamePadding::*;
5755
use self::OutputLocation::*;
5856

59-
use std::boxed::FnBox;
60-
57+
use std::panic::{catch_unwind, AssertUnwindSafe};
6158
use std::any::Any;
6259
use std::cmp;
6360
use std::collections::BTreeMap;
@@ -135,6 +132,16 @@ pub trait TDynBenchFn: Send {
135132
fn run(&self, harness: &mut Bencher);
136133
}
137134

135+
pub trait FnBox<T>: Send + 'static {
136+
fn call_box(self: Box<Self>, t: T);
137+
}
138+
139+
impl<T, F: FnOnce(T) + Send + 'static> FnBox<T> for F {
140+
fn call_box(self: Box<F>, t: T) {
141+
(*self)(t)
142+
}
143+
}
144+
138145
// A function that runs a test. If the function returns successfully,
139146
// the test succeeds; if the function panics then the test fails. We
140147
// may need to come up with a more clever definition of test in order
@@ -143,8 +150,8 @@ pub enum TestFn {
143150
StaticTestFn(fn()),
144151
StaticBenchFn(fn(&mut Bencher)),
145152
StaticMetricFn(fn(&mut MetricMap)),
146-
DynTestFn(Box<FnBox() + Send>),
147-
DynMetricFn(Box<FnBox(&mut MetricMap) + Send>),
153+
DynTestFn(Box<FnBox<()>>),
154+
DynMetricFn(Box<for<'a> FnBox<&'a mut MetricMap>>),
148155
DynBenchFn(Box<TDynBenchFn + 'static>),
149156
}
150157

@@ -1137,23 +1144,25 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
11371144

11381145
pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
11391146
// convert benchmarks to tests, if we're not benchmarking them
1140-
tests.into_iter()
1141-
.map(|x| {
1142-
let testfn = match x.testfn {
1143-
DynBenchFn(bench) => {
1144-
DynTestFn(Box::new(move || bench::run_once(|b| bench.run(b))))
1145-
}
1146-
StaticBenchFn(benchfn) => {
1147-
DynTestFn(Box::new(move || bench::run_once(|b| benchfn(b))))
1148-
}
1149-
f => f,
1150-
};
1151-
TestDescAndFn {
1152-
desc: x.desc,
1153-
testfn: testfn,
1154-
}
1155-
})
1156-
.collect()
1147+
tests.into_iter().map(|x| {
1148+
let testfn = match x.testfn {
1149+
DynBenchFn(bench) => {
1150+
DynTestFn(Box::new(move |()| {
1151+
bench::run_once(|b| bench.run(b))
1152+
}))
1153+
}
1154+
StaticBenchFn(benchfn) => {
1155+
DynTestFn(Box::new(move |()| {
1156+
bench::run_once(|b| benchfn(b))
1157+
}))
1158+
}
1159+
f => f,
1160+
};
1161+
TestDescAndFn {
1162+
desc: x.desc,
1163+
testfn: testfn,
1164+
}
1165+
}).collect()
11571166
}
11581167

11591168
pub fn run_test(opts: &TestOpts,
@@ -1171,7 +1180,7 @@ pub fn run_test(opts: &TestOpts,
11711180
fn run_test_inner(desc: TestDesc,
11721181
monitor_ch: Sender<MonitorMsg>,
11731182
nocapture: bool,
1174-
testfn: Box<FnBox() + Send>) {
1183+
testfn: Box<FnBox<()>>) {
11751184
struct Sink(Arc<Mutex<Vec<u8>>>);
11761185
impl Write for Sink {
11771186
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
@@ -1182,48 +1191,23 @@ pub fn run_test(opts: &TestOpts,
11821191
}
11831192
}
11841193

1185-
// If the platform is single-threaded we're just going to run
1186-
// the test synchronously, regardless of the concurrency
1187-
// level.
1188-
let supports_threads = !cfg!(target_os = "emscripten");
1189-
11901194
// Buffer for capturing standard I/O
11911195
let data = Arc::new(Mutex::new(Vec::new()));
11921196
let data2 = data.clone();
11931197

1194-
if supports_threads {
1195-
thread::spawn(move || {
1196-
let cfg = thread::Builder::new().name(match desc.name {
1197-
DynTestName(ref name) => name.clone(),
1198-
StaticTestName(name) => name.to_owned(),
1199-
});
1200-
1201-
let result_guard = cfg.spawn(move || {
1202-
if !nocapture {
1203-
io::set_print(Some(box Sink(data2.clone())));
1204-
io::set_panic(Some(box Sink(data2)));
1205-
}
1206-
testfn()
1207-
})
1208-
.unwrap();
1209-
let test_result = calc_result(&desc, result_guard.join());
1210-
let stdout = data.lock().unwrap().to_vec();
1211-
monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
1212-
});
1213-
} else {
1198+
let name = desc.name.clone();
1199+
let runtest = move || {
12141200
let oldio = if !nocapture {
12151201
Some((
1216-
io::set_print(Some(box Sink(data2.clone()))),
1217-
io::set_panic(Some(box Sink(data2)))
1202+
io::set_print(Some(Box::new(Sink(data2.clone())))),
1203+
io::set_panic(Some(Box::new(Sink(data2))))
12181204
))
12191205
} else {
12201206
None
12211207
};
12221208

1223-
use std::panic::{catch_unwind, AssertUnwindSafe};
1224-
12251209
let result = catch_unwind(AssertUnwindSafe(|| {
1226-
testfn()
1210+
testfn.call_box(())
12271211
}));
12281212

12291213
if let Some((printio, panicio)) = oldio {
@@ -1234,6 +1218,21 @@ pub fn run_test(opts: &TestOpts,
12341218
let test_result = calc_result(&desc, result);
12351219
let stdout = data.lock().unwrap().to_vec();
12361220
monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
1221+
};
1222+
1223+
1224+
// If the platform is single-threaded we're just going to run
1225+
// the test synchronously, regardless of the concurrency
1226+
// level.
1227+
let supports_threads = !cfg!(target_os = "emscripten");
1228+
if supports_threads {
1229+
let cfg = thread::Builder::new().name(match name {
1230+
DynTestName(ref name) => name.clone(),
1231+
StaticTestName(name) => name.to_owned(),
1232+
});
1233+
cfg.spawn(runtest).unwrap();
1234+
} else {
1235+
runtest();
12371236
}
12381237
}
12391238

@@ -1250,7 +1249,7 @@ pub fn run_test(opts: &TestOpts,
12501249
}
12511250
DynMetricFn(f) => {
12521251
let mut mm = MetricMap::new();
1253-
f.call_box((&mut mm,));
1252+
f.call_box(&mut mm);
12541253
monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap();
12551254
return;
12561255
}
@@ -1261,7 +1260,8 @@ pub fn run_test(opts: &TestOpts,
12611260
return;
12621261
}
12631262
DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f),
1264-
StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(f)),
1263+
StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture,
1264+
Box::new(move |()| f())),
12651265
}
12661266
}
12671267

@@ -1496,7 +1496,7 @@ mod tests {
14961496
ignore: true,
14971497
should_panic: ShouldPanic::No,
14981498
},
1499-
testfn: DynTestFn(Box::new(move || f())),
1499+
testfn: DynTestFn(Box::new(move |()| f())),
15001500
};
15011501
let (tx, rx) = channel();
15021502
run_test(&TestOpts::new(), false, desc, tx);
@@ -1513,7 +1513,7 @@ mod tests {
15131513
ignore: true,
15141514
should_panic: ShouldPanic::No,
15151515
},
1516-
testfn: DynTestFn(Box::new(move || f())),
1516+
testfn: DynTestFn(Box::new(move |()| f())),
15171517
};
15181518
let (tx, rx) = channel();
15191519
run_test(&TestOpts::new(), false, desc, tx);
@@ -1532,7 +1532,7 @@ mod tests {
15321532
ignore: false,
15331533
should_panic: ShouldPanic::Yes,
15341534
},
1535-
testfn: DynTestFn(Box::new(move || f())),
1535+
testfn: DynTestFn(Box::new(move |()| f())),
15361536
};
15371537
let (tx, rx) = channel();
15381538
run_test(&TestOpts::new(), false, desc, tx);
@@ -1551,7 +1551,7 @@ mod tests {
15511551
ignore: false,
15521552
should_panic: ShouldPanic::YesWithMessage("error message"),
15531553
},
1554-
testfn: DynTestFn(Box::new(move || f())),
1554+
testfn: DynTestFn(Box::new(move |()| f())),
15551555
};
15561556
let (tx, rx) = channel();
15571557
run_test(&TestOpts::new(), false, desc, tx);
@@ -1570,7 +1570,7 @@ mod tests {
15701570
ignore: false,
15711571
should_panic: ShouldPanic::YesWithMessage("foobar"),
15721572
},
1573-
testfn: DynTestFn(Box::new(move || f())),
1573+
testfn: DynTestFn(Box::new(move |()| f())),
15741574
};
15751575
let (tx, rx) = channel();
15761576
run_test(&TestOpts::new(), false, desc, tx);
@@ -1587,7 +1587,7 @@ mod tests {
15871587
ignore: false,
15881588
should_panic: ShouldPanic::Yes,
15891589
},
1590-
testfn: DynTestFn(Box::new(move || f())),
1590+
testfn: DynTestFn(Box::new(move |()| f())),
15911591
};
15921592
let (tx, rx) = channel();
15931593
run_test(&TestOpts::new(), false, desc, tx);
@@ -1620,15 +1620,15 @@ mod tests {
16201620
ignore: true,
16211621
should_panic: ShouldPanic::No,
16221622
},
1623-
testfn: DynTestFn(Box::new(move || {})),
1623+
testfn: DynTestFn(Box::new(move |()| {})),
16241624
},
16251625
TestDescAndFn {
16261626
desc: TestDesc {
16271627
name: StaticTestName("2"),
16281628
ignore: false,
16291629
should_panic: ShouldPanic::No,
16301630
},
1631-
testfn: DynTestFn(Box::new(move || {})),
1631+
testfn: DynTestFn(Box::new(move |()| {})),
16321632
}];
16331633
let filtered = filter_tests(&opts, tests);
16341634

@@ -1661,7 +1661,7 @@ mod tests {
16611661
ignore: false,
16621662
should_panic: ShouldPanic::No,
16631663
},
1664-
testfn: DynTestFn(Box::new(testfn)),
1664+
testfn: DynTestFn(Box::new(move |()| testfn())),
16651665
};
16661666
tests.push(test);
16671667
}

src/tools/compiletest/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName
464464
pub fn make_test_closure(config: &Config, testpaths: &TestPaths) -> test::TestFn {
465465
let config = config.clone();
466466
let testpaths = testpaths.clone();
467-
test::DynTestFn(Box::new(move || {
467+
test::DynTestFn(Box::new(move |()| {
468468
runtest::run(config, &testpaths)
469469
}))
470470
}

0 commit comments

Comments
 (0)