@@ -293,7 +293,7 @@ fn run_compiler(
293293 >,
294294 using_internal_features: Arc <std:: sync:: atomic:: AtomicBool >,
295295) -> interface:: Result <( ) > {
296- let mut early_error_handler = EarlyErrorHandler :: new( ErrorOutputType :: default ( ) ) ;
296+ let mut default_handler = EarlyErrorHandler :: new( ErrorOutputType :: default ( ) ) ;
297297
298298 // Throw away the first argument, the name of the binary.
299299 // In case of at_args being empty, as might be the case by
@@ -305,14 +305,14 @@ fn run_compiler(
305305 // the compiler with @empty_file as argv[0] and no more arguments.
306306 let at_args = at_args. get( 1 ..) . unwrap_or_default( ) ;
307307
308- let args = args:: arg_expand_all( & early_error_handler , at_args) ;
308+ let args = args:: arg_expand_all( & default_handler , at_args) ;
309309
310- let Some ( matches) = handle_options( & early_error_handler , & args) else { return Ok ( ( ) ) } ;
310+ let Some ( matches) = handle_options( & default_handler , & args) else { return Ok ( ( ) ) } ;
311311
312- let sopts = config:: build_session_options( & mut early_error_handler , & matches) ;
312+ let sopts = config:: build_session_options( & mut default_handler , & matches) ;
313313
314314 if let Some ( ref code) = matches. opt_str( "explain" ) {
315- handle_explain( & early_error_handler , diagnostics_registry( ) , code, sopts. color) ;
315+ handle_explain( & default_handler , diagnostics_registry( ) , code, sopts. color) ;
316316 return Ok ( ( ) ) ;
317317 }
318318
@@ -338,61 +338,56 @@ fn run_compiler(
338338 expanded_args: args,
339339 } ;
340340
341- match make_input( & early_error_handler , & matches. free) {
341+ let has_input = match make_input( & default_handler , & matches. free) {
342342 Err ( reported) => return Err ( reported) ,
343343 Ok ( Some ( input) ) => {
344344 config. input = input;
345-
346- callbacks. config( & mut config) ;
345+ true // has input: normal compilation
347346 }
348347 Ok ( None ) => match matches. free. len( ) {
349- 0 => {
350- callbacks. config( & mut config) ;
351-
352- early_error_handler. abort_if_errors( ) ;
353-
354- interface:: run_compiler( config, |compiler| {
355- let sopts = & compiler. session( ) . opts;
356- let handler = EarlyErrorHandler :: new( sopts. error_format) ;
357-
358- if sopts. describe_lints {
359- describe_lints( compiler. session( ) ) ;
360- return ;
361- }
362- let should_stop = print_crate_info(
363- & handler,
364- compiler. codegen_backend( ) ,
365- compiler. session( ) ,
366- false ,
367- ) ;
368-
369- if should_stop == Compilation :: Stop {
370- return ;
371- }
372- handler. early_error( "no input filename given" )
373- } ) ;
374- return Ok ( ( ) ) ;
375- }
348+ 0 => false , // no input: we will exit early
376349 1 => panic!( "make_input should have provided valid inputs" ) ,
377- _ => early_error_handler . early_error( format!(
350+ _ => default_handler . early_error( format!(
378351 "multiple input filenames provided (first two filenames are `{}` and `{}`)" ,
379352 matches. free[ 0 ] , matches. free[ 1 ] ,
380353 ) ) ,
381354 } ,
382355 } ;
383356
384- early_error_handler. abort_if_errors( ) ;
357+ callbacks. config( & mut config) ;
358+
359+ default_handler. abort_if_errors( ) ;
360+ drop( default_handler) ;
385361
386362 interface:: run_compiler( config, |compiler| {
387363 let sess = compiler. session( ) ;
388364 let codegen_backend = compiler. codegen_backend( ) ;
365+
366+ // This implements `-Whelp`. It should be handled very early, like
367+ // `--help`/`-Zhelp`/`-Chelp`. This is the earliest it can run, because
368+ // it must happen after lints are registered, during session creation.
369+ if sess. opts. describe_lints {
370+ describe_lints( sess) ;
371+ return sess. compile_status( ) ;
372+ }
373+
389374 let handler = EarlyErrorHandler :: new( sess. opts. error_format) ;
390375
391- let should_stop = print_crate_info( & handler, codegen_backend, sess, true )
392- . and_then( || list_metadata( & handler, sess, & * codegen_backend. metadata_loader( ) ) )
393- . and_then( || try_process_rlink( sess, compiler) ) ;
376+ if print_crate_info( & handler, codegen_backend, sess, has_input) == Compilation :: Stop {
377+ return sess. compile_status( ) ;
378+ }
379+
380+ if !has_input {
381+ handler. early_error( "no input filename given" ) ; // this is fatal
382+ }
383+
384+ if !sess. opts. unstable_opts. ls. is_empty( ) {
385+ list_metadata( & handler, sess, & * codegen_backend. metadata_loader( ) ) ;
386+ return sess. compile_status( ) ;
387+ }
394388
395- if should_stop == Compilation :: Stop {
389+ if sess. opts. unstable_opts. link_only {
390+ process_rlink( sess, compiler) ;
396391 return sess. compile_status( ) ;
397392 }
398393
@@ -431,11 +426,6 @@ fn run_compiler(
431426 return early_exit( ) ;
432427 }
433428
434- if sess. opts. describe_lints {
435- describe_lints( sess) ;
436- return early_exit( ) ;
437- }
438-
439429 // Make sure name resolution and macro expansion is run.
440430 queries. global_ctxt( ) ?. enter( |tcx| tcx. resolver_for_lowering( ( ) ) ) ;
441431
@@ -550,15 +540,6 @@ pub enum Compilation {
550540 Continue ,
551541}
552542
553- impl Compilation {
554- fn and_then<F : FnOnce ( ) -> Compilation >( self , next: F ) -> Compilation {
555- match self {
556- Compilation :: Stop => Compilation :: Stop ,
557- Compilation :: Continue => next( ) ,
558- }
559- }
560- }
561-
562543fn handle_explain( handler: & EarlyErrorHandler , registry: Registry , code: & str , color: ColorConfig ) {
563544 let upper_cased_code = code. to_ascii_uppercase( ) ;
564545 let normalised =
@@ -663,70 +644,60 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
663644 }
664645}
665646
666- fn try_process_rlink( sess: & Session , compiler: & interface:: Compiler ) -> Compilation {
667- if sess. opts. unstable_opts. link_only {
668- if let Input :: File ( file) = & sess. io. input {
669- let outputs = compiler. build_output_filenames( sess, & [ ] ) ;
670- let rlink_data = fs:: read( file) . unwrap_or_else( |err| {
671- sess. emit_fatal( RlinkUnableToRead { err } ) ;
672- } ) ;
673- let codegen_results = match CodegenResults :: deserialize_rlink( sess, rlink_data) {
674- Ok ( codegen) => codegen,
675- Err ( err) => {
676- match err {
677- CodegenErrors :: WrongFileType => sess. emit_fatal( RLinkWrongFileType ) ,
678- CodegenErrors :: EmptyVersionNumber => {
679- sess. emit_fatal( RLinkEmptyVersionNumber )
680- }
681- CodegenErrors :: EncodingVersionMismatch { version_array, rlink_version } => {
682- sess. emit_fatal( RLinkEncodingVersionMismatch {
683- version_array,
684- rlink_version,
685- } )
686- }
687- CodegenErrors :: RustcVersionMismatch { rustc_version } => {
688- sess. emit_fatal( RLinkRustcVersionMismatch {
689- rustc_version,
690- current_version: sess. cfg_version,
691- } )
692- }
693- } ;
694- }
695- } ;
696- let result = compiler. codegen_backend( ) . link( sess, codegen_results, & outputs) ;
697- abort_on_err( result, sess) ;
698- } else {
699- sess. emit_fatal( RlinkNotAFile { } )
700- }
701- Compilation :: Stop
647+ fn process_rlink( sess: & Session , compiler: & interface:: Compiler ) {
648+ assert!( sess. opts. unstable_opts. link_only) ;
649+ if let Input :: File ( file) = & sess. io. input {
650+ let outputs = compiler. build_output_filenames( sess, & [ ] ) ;
651+ let rlink_data = fs:: read( file) . unwrap_or_else( |err| {
652+ sess. emit_fatal( RlinkUnableToRead { err } ) ;
653+ } ) ;
654+ let codegen_results = match CodegenResults :: deserialize_rlink( sess, rlink_data) {
655+ Ok ( codegen) => codegen,
656+ Err ( err) => {
657+ match err {
658+ CodegenErrors :: WrongFileType => sess. emit_fatal( RLinkWrongFileType ) ,
659+ CodegenErrors :: EmptyVersionNumber => sess. emit_fatal( RLinkEmptyVersionNumber ) ,
660+ CodegenErrors :: EncodingVersionMismatch { version_array, rlink_version } => sess
661+ . emit_fatal( RLinkEncodingVersionMismatch { version_array, rlink_version } ) ,
662+ CodegenErrors :: RustcVersionMismatch { rustc_version } => {
663+ sess. emit_fatal( RLinkRustcVersionMismatch {
664+ rustc_version,
665+ current_version: sess. cfg_version,
666+ } )
667+ }
668+ } ;
669+ }
670+ } ;
671+ let result = compiler. codegen_backend( ) . link( sess, codegen_results, & outputs) ;
672+ abort_on_err( result, sess) ;
702673 } else {
703- Compilation :: Continue
674+ sess . emit_fatal ( RlinkNotAFile { } )
704675 }
705676}
706677
707678fn list_metadata(
708679 handler: & EarlyErrorHandler ,
709680 sess: & Session ,
710681 metadata_loader: & dyn MetadataLoader ,
711- ) -> Compilation {
712- let ls_kinds = & sess. opts. unstable_opts. ls;
713- if !ls_kinds. is_empty( ) {
714- match sess. io. input {
715- Input :: File ( ref ifile) => {
716- let path = & ( * ifile) ;
717- let mut v = Vec :: new( ) ;
718- locator:: list_file_metadata( & sess. target, path, metadata_loader, & mut v, ls_kinds)
719- . unwrap( ) ;
720- safe_println!( "{}" , String :: from_utf8( v) . unwrap( ) ) ;
721- }
722- Input :: Str { .. } => {
723- handler. early_error( "cannot list metadata for stdin" ) ;
724- }
682+ ) {
683+ match sess. io. input {
684+ Input :: File ( ref ifile) => {
685+ let path = & ( * ifile) ;
686+ let mut v = Vec :: new( ) ;
687+ locator:: list_file_metadata(
688+ & sess. target,
689+ path,
690+ metadata_loader,
691+ & mut v,
692+ & sess. opts. unstable_opts. ls,
693+ )
694+ . unwrap( ) ;
695+ safe_println!( "{}" , String :: from_utf8( v) . unwrap( ) ) ;
696+ }
697+ Input :: Str { .. } => {
698+ handler. early_error( "cannot list metadata for stdin" ) ;
725699 }
726- return Compilation :: Stop ;
727700 }
728-
729- Compilation :: Continue
730701}
731702
732703fn print_crate_info(
0 commit comments