@@ -18,6 +18,7 @@ use rustc_session::{EarlyDiagCtxt, getopts};
1818use rustc_span:: edition:: Edition ;
1919use rustc_span:: { FileName , RemapPathScopeComponents } ;
2020use rustc_target:: spec:: TargetTuple ;
21+ use smallvec:: SmallVec ;
2122
2223use crate :: core:: new_dcx;
2324use crate :: externalfiles:: ExternalHtml ;
@@ -293,7 +294,7 @@ pub(crate) struct RenderOptions {
293294 /// Note: this field is duplicated in `Options` because it's useful to have
294295 /// it in both places.
295296 pub ( crate ) unstable_features : rustc_feature:: UnstableFeatures ,
296- pub ( crate ) emit : Vec < EmitType > ,
297+ pub ( crate ) emit : SmallVec < [ EmitType ; 2 ] > ,
297298 /// If `true`, HTML source pages will generate links for items to their definition.
298299 pub ( crate ) generate_link_to_definition : bool ,
299300 /// Set of function-call locations to include as examples
@@ -327,9 +328,22 @@ pub(crate) enum ModuleSorting {
327328pub ( crate ) enum EmitType {
328329 HtmlStaticFiles ,
329330 HtmlNonStaticFiles ,
331+ // not explicitly nameable by the user for now
332+ JsonFiles ,
330333 DepInfo ( Option < OutFileName > ) ,
331334}
332335
336+ impl fmt:: Display for EmitType {
337+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
338+ f. write_str ( match self {
339+ Self :: HtmlStaticFiles => "html-static-files" ,
340+ Self :: HtmlNonStaticFiles => "html-non-static-files" ,
341+ Self :: JsonFiles => "json-files" ,
342+ Self :: DepInfo ( _) => "dep-info" ,
343+ } )
344+ }
345+ }
346+
333347impl FromStr for EmitType {
334348 type Err = ( ) ;
335349
@@ -352,17 +366,11 @@ impl FromStr for EmitType {
352366}
353367
354368impl RenderOptions {
355- pub ( crate ) fn should_emit_crate ( & self ) -> bool {
356- self . emit . is_empty ( ) || self . emit . contains ( & EmitType :: HtmlNonStaticFiles )
357- }
358-
359369 pub ( crate ) fn dep_info ( & self ) -> Option < Option < & OutFileName > > {
360- for emit in & self . emit {
361- if let EmitType :: DepInfo ( file) = emit {
362- return Some ( file. as_ref ( ) ) ;
363- }
364- }
365- None
370+ self . emit . iter ( ) . find_map ( |emit| match emit {
371+ EmitType :: DepInfo ( file) => Some ( file. as_ref ( ) ) ,
372+ _ => None ,
373+ } )
366374 }
367375}
368376
@@ -469,26 +477,6 @@ impl Options {
469477
470478 let should_test = matches. opt_present ( "test" ) ;
471479
472- let mut emit = FxIndexMap :: < _ , EmitType > :: default ( ) ;
473- for list in matches. opt_strs ( "emit" ) {
474- if should_test {
475- dcx. fatal ( "the `--test` flag and the `--emit` flag are not supported together" ) ;
476- }
477- for kind in list. split ( ',' ) {
478- match kind. parse ( ) {
479- Ok ( kind) => {
480- // De-duplicate emit types and the last wins.
481- // Only one instance for each type is allowed
482- // regardless the actual data it carries.
483- // This matches rustc's `--emit` behavior.
484- emit. insert ( std:: mem:: discriminant ( & kind) , kind) ;
485- }
486- Err ( ( ) ) => dcx. fatal ( format ! ( "unrecognized emission type: {kind}" ) ) ,
487- }
488- }
489- }
490- let emit = emit. into_values ( ) . collect :: < Vec < _ > > ( ) ;
491-
492480 let show_coverage = matches. opt_present ( "show-coverage" ) ;
493481 let output_format_s = matches. opt_str ( "output-format" ) ;
494482 let output_format = match output_format_s {
@@ -527,15 +515,55 @@ impl Options {
527515 }
528516 }
529517
530- if output_format == OutputFormat :: Json {
531- if let Some ( emit_flag) = emit. iter ( ) . find_map ( |emit| match emit {
532- EmitType :: HtmlStaticFiles => Some ( "html-static-files" ) ,
533- EmitType :: HtmlNonStaticFiles => Some ( "html-non-static-files" ) ,
534- EmitType :: DepInfo ( _) => None ,
535- } ) {
536- dcx. fatal ( format ! (
537- "the `--emit={emit_flag}` flag is not supported with `--output-format=json`" ,
538- ) ) ;
518+ let mut emit = FxIndexMap :: default ( ) ;
519+ for list in matches. opt_strs ( "emit" ) {
520+ if should_test {
521+ dcx. fatal ( "the `--test` flag and the `--emit` flag are not supported together" ) ;
522+ }
523+ if let OutputFormat :: Doctest = output_format {
524+ dcx. fatal ( "the `--emit` flag is not supported with `--output-format=doctest`" ) ;
525+ }
526+
527+ for typ in list. split ( ',' ) {
528+ let Ok ( typ) = typ. parse :: < EmitType > ( ) else {
529+ dcx. fatal ( format ! ( "unrecognized emission type: {typ}" ) )
530+ } ;
531+
532+ match typ {
533+ EmitType :: DepInfo ( _) => match output_format {
534+ OutputFormat :: Json | OutputFormat :: Html => { }
535+ OutputFormat :: Doctest => unreachable ! ( ) ,
536+ } ,
537+ EmitType :: HtmlStaticFiles | EmitType :: HtmlNonStaticFiles => match output_format
538+ {
539+ OutputFormat :: Html => { }
540+ OutputFormat :: Json => dcx. fatal ( format ! (
541+ "the `--emit={typ}` flag is not supported with `--output-format=json`" ,
542+ ) ) ,
543+ OutputFormat :: Doctest => unreachable ! ( ) ,
544+ } ,
545+ EmitType :: JsonFiles => unreachable ! ( ) ,
546+ }
547+
548+ // De-duplicate emit types and the last wins.
549+ // Only one instance for each type is allowed
550+ // regardless the actual data it carries.
551+ // This matches rustc's `--emit` behavior.
552+ emit. insert ( std:: mem:: discriminant ( & typ) , typ) ;
553+ }
554+ }
555+ let mut emit: SmallVec < [ _ ; 2 ] > = emit. into_values ( ) . collect ( ) ;
556+ // If `--emit` is absent we'll register default emission types depending on the requested
557+ // output format. We can safely use `is_empty` for this since `--emit=` ("truly empty")
558+ // will have already been rejected above.
559+ if emit. is_empty ( ) {
560+ match output_format {
561+ OutputFormat :: Json => emit. push ( EmitType :: JsonFiles ) ,
562+ OutputFormat :: Html => {
563+ emit. push ( EmitType :: HtmlStaticFiles ) ;
564+ emit. push ( EmitType :: HtmlNonStaticFiles ) ;
565+ }
566+ OutputFormat :: Doctest => { }
539567 }
540568 }
541569
0 commit comments