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::*;
5654use self :: NamePadding :: * ;
5755use self :: OutputLocation :: * ;
5856
59- use std:: boxed:: FnBox ;
60-
57+ use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
6158use std:: any:: Any ;
6259use std:: cmp;
6360use 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
11381145pub 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
11591168pub 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 }
0 commit comments