@@ -82,6 +82,7 @@ use rustc::util::common::time;
8282
8383use serialize:: json:: ToJson ;
8484
85+ use std:: any:: Any ;
8586use std:: cmp:: max;
8687use std:: cmp:: Ordering :: Equal ;
8788use std:: default:: Default ;
@@ -1018,15 +1019,34 @@ fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<as
10181019 }
10191020}
10201021
1022+ /// Runs `f` in a suitable thread for running `rustc`; returns a
1023+ /// `Result` with either the return value of `f` or -- if a panic
1024+ /// occurs -- the panic value.
1025+ pub fn in_rustc_thread < F , R > ( f : F ) -> Result < R , Box < Any + Send > >
1026+ where F : FnOnce ( ) -> R + Send + ' static ,
1027+ R : Send + ' static ,
1028+ {
1029+ // Temporarily have stack size set to 16MB to deal with nom-using crates failing
1030+ const STACK_SIZE : usize = 16 * 1024 * 1024 ; // 16MB
1031+
1032+ let mut cfg = thread:: Builder :: new ( ) . name ( "rustc" . to_string ( ) ) ;
1033+
1034+ // FIXME: Hacks on hacks. If the env is trying to override the stack size
1035+ // then *don't* set it explicitly.
1036+ if env:: var_os ( "RUST_MIN_STACK" ) . is_none ( ) {
1037+ cfg = cfg. stack_size ( STACK_SIZE ) ;
1038+ }
1039+
1040+ let thread = cfg. spawn ( f) ;
1041+ thread. unwrap ( ) . join ( )
1042+ }
1043+
10211044/// Run a procedure which will detect panics in the compiler and print nicer
10221045/// error messages rather than just failing the test.
10231046///
10241047/// The diagnostic emitter yielded to the procedure should be used for reporting
10251048/// errors of the compiler.
10261049pub fn monitor < F : FnOnce ( ) + Send + ' static > ( f : F ) {
1027- // Temporarily have stack size set to 16MB to deal with nom-using crates failing
1028- const STACK_SIZE : usize = 16 * 1024 * 1024 ; // 16MB
1029-
10301050 struct Sink ( Arc < Mutex < Vec < u8 > > > ) ;
10311051 impl Write for Sink {
10321052 fn write ( & mut self , data : & [ u8 ] ) -> io:: Result < usize > {
@@ -1040,20 +1060,12 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
10401060 let data = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
10411061 let err = Sink ( data. clone ( ) ) ;
10421062
1043- let mut cfg = thread:: Builder :: new ( ) . name ( "rustc" . to_string ( ) ) ;
1044-
1045- // FIXME: Hacks on hacks. If the env is trying to override the stack size
1046- // then *don't* set it explicitly.
1047- if env:: var_os ( "RUST_MIN_STACK" ) . is_none ( ) {
1048- cfg = cfg. stack_size ( STACK_SIZE ) ;
1049- }
1050-
1051- let thread = cfg. spawn ( move || {
1052- io:: set_panic ( Some ( box err) ) ;
1053- f ( )
1054- } ) ;
1063+ let result = in_rustc_thread ( move || {
1064+ io:: set_panic ( Some ( box err) ) ;
1065+ f ( )
1066+ } ) ;
10551067
1056- if let Err ( value) = thread . unwrap ( ) . join ( ) {
1068+ if let Err ( value) = result {
10571069 // Thread panicked without emitting a fatal diagnostic
10581070 if !value. is :: < errors:: FatalError > ( ) {
10591071 let emitter =
0 commit comments