1414pub use self :: EntryFnType :: * ;
1515pub use self :: CrateType :: * ;
1616pub use self :: Passes :: * ;
17- pub use self :: OptLevel :: * ;
1817pub use self :: DebugInfoLevel :: * ;
1918
2019use session:: { early_error, early_warn, Session } ;
@@ -71,6 +70,18 @@ pub enum OutputType {
7170 DepInfo ,
7271}
7372
73+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
74+ pub enum ErrorOutputType {
75+ Tty ( ColorConfig ) ,
76+ Json ,
77+ }
78+
79+ impl Default for ErrorOutputType {
80+ fn default ( ) -> ErrorOutputType {
81+ ErrorOutputType :: Tty ( ColorConfig :: Auto )
82+ }
83+ }
84+
7485impl OutputType {
7586 fn is_compatible_with_codegen_units_and_single_output_file ( & self ) -> bool {
7687 match * self {
@@ -124,14 +135,14 @@ pub struct Options {
124135 pub test : bool ,
125136 pub parse_only : bool ,
126137 pub no_trans : bool ,
138+ pub output : ErrorOutputType ,
127139 pub treat_err_as_bug : bool ,
128140 pub incremental_compilation : bool ,
129141 pub dump_dep_graph : bool ,
130142 pub no_analysis : bool ,
131143 pub debugging_opts : DebuggingOptions ,
132144 pub prints : Vec < PrintRequest > ,
133145 pub cg : CodegenOptions ,
134- pub color : ColorConfig ,
135146 pub externs : HashMap < String , Vec < String > > ,
136147 pub crate_name : Option < String > ,
137148 /// An optional name to use as the crate for std during std injection,
@@ -221,7 +232,7 @@ pub fn basic_options() -> Options {
221232 Options {
222233 crate_types : Vec :: new ( ) ,
223234 gc : false ,
224- optimize : No ,
235+ optimize : OptLevel :: No ,
225236 debuginfo : NoDebugInfo ,
226237 lint_opts : Vec :: new ( ) ,
227238 lint_cap : None ,
@@ -241,7 +252,12 @@ pub fn basic_options() -> Options {
241252 debugging_opts : basic_debugging_options ( ) ,
242253 prints : Vec :: new ( ) ,
243254 cg : basic_codegen_options ( ) ,
255+ <<<<<<< HEAD
244256 color: ColorConfig :: Auto ,
257+ =======
258+ output: ErrorOutputType :: default ( ) ,
259+ show_span : None ,
260+ >>>>>>> Add an --output option for specifying an error emitter
245261 externs: HashMap :: new ( ) ,
246262 crate_name: None ,
247263 alt_std_name: None ,
@@ -308,7 +324,7 @@ macro_rules! options {
308324 $struct_name { $( $opt: $init) , * }
309325 }
310326
311- pub fn $buildfn( matches: & getopts:: Matches , color : ColorConfig ) -> $struct_name
327+ pub fn $buildfn( matches: & getopts:: Matches , output : ErrorOutputType ) -> $struct_name
312328 {
313329 let mut op = $defaultfn( ) ;
314330 for option in matches. opt_strs( $prefix) {
@@ -322,17 +338,17 @@ macro_rules! options {
322338 if !setter( & mut op, value) {
323339 match ( value, opt_type_desc) {
324340 ( Some ( ..) , None ) => {
325- early_error( color , & format!( "{} option `{}` takes no \
341+ early_error( output , & format!( "{} option `{}` takes no \
326342 value", $outputname, key) )
327343 }
328344 ( None , Some ( type_desc) ) => {
329- early_error( color , & format!( "{0} option `{1}` requires \
345+ early_error( output , & format!( "{0} option `{1}` requires \
330346 {2} ({3} {1}=<value>)",
331347 $outputname, key,
332348 type_desc, $prefix) )
333349 }
334350 ( Some ( value) , Some ( type_desc) ) => {
335- early_error( color , & format!( "incorrect value `{}` for {} \
351+ early_error( output , & format!( "incorrect value `{}` for {} \
336352 option `{}` - {} was expected",
337353 value, $outputname,
338354 key, type_desc) )
@@ -344,7 +360,7 @@ macro_rules! options {
344360 break ;
345361 }
346362 if !found {
347- early_error( color , & format!( "unknown {} option: `{}`" ,
363+ early_error( output , & format!( "unknown {} option: `{}`" ,
348364 $outputname, key) ) ;
349365 }
350366 }
@@ -863,6 +879,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
863879 "NAME=PATH" ) ,
864880 opt:: opt( "" , "sysroot" , "Override the system root" , "PATH" ) ,
865881 opt:: multi( "Z" , "" , "Set internal debugging options" , "FLAG" ) ,
882+ opt:: opt_u( "" , "output" , "How errors and other mesasges are produced" , "tty|json" ) ,
866883 opt:: opt( "" , "color" , "Configure coloring of output:
867884 auto = colorize, if output goes to a tty (default);
868885 always = always colorize output;
@@ -905,15 +922,36 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
905922 None => ColorConfig :: Auto ,
906923
907924 Some ( arg) => {
908- early_error ( ColorConfig :: Auto , & format ! ( "argument for --color must be auto, always \
909- or never (instead was `{}`)",
910- arg) )
925+ early_error( ErrorOutputType :: default ( ) , & format!( "argument for --color must be auto, \
926+ always or never (instead was `{}`)",
927+ arg) )
911928 }
912929 } ;
913930
931+ // We need the opts_present check because the driver will send us Matches
932+ // with only stable options if no unstable options are used. Since output is
933+ // unstable, it will not be present. We have to use opts_present not
934+ // opt_present because the latter will panic.
935+ let output = if matches. opts_present( & [ "output" . to_owned( ) ] ) {
936+ match matches. opt_str( "output" ) . as_ref( ) . map( |s| & s[ ..] ) {
937+ Some ( "tty" ) => ErrorOutputType :: Tty ( color) ,
938+ Some ( "json" ) => ErrorOutputType :: Json ,
939+
940+ None => ErrorOutputType :: default ( ) ,
941+
942+ Some ( arg) => {
943+ early_error( ErrorOutputType :: default ( ) , & format!( "argument for --output must be tty or \
944+ json (instead was `{}`)",
945+ arg) )
946+ }
947+ }
948+ } else {
949+ ErrorOutputType :: default ( )
950+ } ;
951+
914952 let unparsed_crate_types = matches. opt_strs( "crate-type" ) ;
915953 let crate_types = parse_crate_types_from_list( unparsed_crate_types)
916- . unwrap_or_else ( |e| early_error ( color , & e[ ..] ) ) ;
954+ . unwrap_or_else( |e| early_error( output , & e[ ..] ) ) ;
917955
918956 let mut lint_opts = vec!( ) ;
919957 let mut describe_lints = false ;
@@ -930,11 +968,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
930968
931969 let lint_cap = matches. opt_str( "cap-lints" ) . map( |cap| {
932970 lint:: Level :: from_str( & cap) . unwrap_or_else( || {
933- early_error ( color , & format ! ( "unknown lint level: `{}`" , cap) )
971+ early_error( output , & format!( "unknown lint level: `{}`" , cap) )
934972 } )
935973 } ) ;
936974
937- let debugging_opts = build_debugging_options ( matches, color ) ;
975+ let debugging_opts = build_debugging_options( matches, output ) ;
938976
939977 let parse_only = debugging_opts. parse_only;
940978 let no_trans = debugging_opts. no_trans;
@@ -960,7 +998,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
960998 "link" => OutputType :: Exe ,
961999 "dep-info" => OutputType :: DepInfo ,
9621000 part => {
963- early_error ( color , & format ! ( "unknown emission type: `{}`" ,
1001+ early_error( output , & format!( "unknown emission type: `{}`" ,
9641002 part) )
9651003 }
9661004 } ;
@@ -973,7 +1011,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
9731011 output_types. insert( OutputType :: Exe , None ) ;
9741012 }
9751013
976- let mut cg = build_codegen_options ( matches, color ) ;
1014+ let mut cg = build_codegen_options( matches, output ) ;
9771015
9781016 // Issue #30063: if user requests llvm-related output to one
9791017 // particular path, disable codegen-units.
@@ -985,11 +1023,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
9851023 } ) . collect( ) ;
9861024 if !incompatible. is_empty( ) {
9871025 for ot in & incompatible {
988- early_warn ( color , & format ! ( "--emit={} with -o incompatible with \
1026+ early_warn( output , & format!( "--emit={} with -o incompatible with \
9891027 -C codegen-units=N for N > 1",
9901028 ot. shorthand( ) ) ) ;
9911029 }
992- early_warn ( color , "resetting to default -C codegen-units=1" ) ;
1030+ early_warn( output , "resetting to default -C codegen-units=1" ) ;
9931031 cg. codegen_units = 1 ;
9941032 }
9951033 }
@@ -1002,29 +1040,29 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10021040 let opt_level = {
10031041 if matches. opt_present( "O" ) {
10041042 if cg. opt_level. is_some( ) {
1005- early_error ( color , "-O and -C opt-level both provided" ) ;
1043+ early_error( output , "-O and -C opt-level both provided" ) ;
10061044 }
1007- Default
1045+ OptLevel :: Default
10081046 } else {
10091047 match cg. opt_level {
1010- None => No ,
1011- Some ( 0 ) => No ,
1012- Some ( 1 ) => Less ,
1013- Some ( 2 ) => Default ,
1014- Some ( 3 ) => Aggressive ,
1048+ None => OptLevel :: No ,
1049+ Some ( 0 ) => OptLevel :: No ,
1050+ Some ( 1 ) => OptLevel :: Less ,
1051+ Some ( 2 ) => OptLevel :: Default ,
1052+ Some ( 3 ) => OptLevel :: Aggressive ,
10151053 Some ( arg) => {
1016- early_error ( color , & format ! ( "optimization level needs to be \
1054+ early_error( output , & format!( "optimization level needs to be \
10171055 between 0-3 (instead was `{}`)",
10181056 arg) ) ;
10191057 }
10201058 }
10211059 }
10221060 } ;
1023- let debug_assertions = cg. debug_assertions . unwrap_or ( opt_level == No ) ;
1061+ let debug_assertions = cg. debug_assertions. unwrap_or( opt_level == OptLevel :: No ) ;
10241062 let gc = debugging_opts. gc;
10251063 let debuginfo = if matches. opt_present( "g" ) {
10261064 if cg. debuginfo. is_some( ) {
1027- early_error ( color , "-g and -C debuginfo both provided" ) ;
1065+ early_error( output , "-g and -C debuginfo both provided" ) ;
10281066 }
10291067 FullDebugInfo
10301068 } else {
@@ -1033,7 +1071,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10331071 Some ( 1 ) => LimitedDebugInfo ,
10341072 Some ( 2 ) => FullDebugInfo ,
10351073 Some ( arg) => {
1036- early_error ( color , & format ! ( "debug info level needs to be between \
1074+ early_error( output , & format!( "debug info level needs to be between \
10371075 0-2 (instead was `{}`)",
10381076 arg) ) ;
10391077 }
@@ -1042,7 +1080,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10421080
10431081 let mut search_paths = SearchPaths :: new( ) ;
10441082 for s in & matches. opt_strs( "L" ) {
1045- search_paths. add_path ( & s[ ..] , color ) ;
1083+ search_paths. add_path( & s[ ..] , output ) ;
10461084 }
10471085
10481086 let libs = matches. opt_strs( "l" ) . into_iter( ) . map( |s| {
@@ -1054,7 +1092,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10541092 ( Some ( name) , "framework" ) => ( name, cstore:: NativeFramework ) ,
10551093 ( Some ( name) , "static" ) => ( name, cstore:: NativeStatic ) ,
10561094 ( _, s) => {
1057- early_error ( color , & format ! ( "unknown library kind `{}`, expected \
1095+ early_error( output , & format!( "unknown library kind `{}`, expected \
10581096 one of dylib, framework, or static",
10591097 s) ) ;
10601098 }
@@ -1071,13 +1109,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10711109 "file-names" => PrintRequest :: FileNames ,
10721110 "sysroot" => PrintRequest :: Sysroot ,
10731111 req => {
1074- early_error ( color , & format ! ( "unknown print request `{}`" , req) )
1112+ early_error( output , & format!( "unknown print request `{}`" , req) )
10751113 }
10761114 }
10771115 } ) . collect:: <Vec <_>>( ) ;
10781116
10791117 if !cg. remark. is_empty( ) && debuginfo == NoDebugInfo {
1080- early_warn ( color , "-C remark will not show source locations without \
1118+ early_warn( output , "-C remark will not show source locations without \
10811119 --debuginfo") ;
10821120 }
10831121
@@ -1086,11 +1124,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
10861124 let mut parts = arg. splitn( 2 , '=' ) ;
10871125 let name = match parts. next( ) {
10881126 Some ( s) => s,
1089- None => early_error ( color , "--extern value must not be empty" ) ,
1127+ None => early_error( output , "--extern value must not be empty" ) ,
10901128 } ;
10911129 let location = match parts. next( ) {
10921130 Some ( s) => s,
1093- None => early_error ( color , "--extern value must be of the format `foo=bar`" ) ,
1131+ None => early_error( output , "--extern value must be of the format `foo=bar`" ) ,
10941132 } ;
10951133
10961134 externs. entry( name. to_string( ) ) . or_insert( vec![ ] ) . push( location. to_string( ) ) ;
@@ -1121,7 +1159,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
11211159 debugging_opts: debugging_opts,
11221160 prints: prints,
11231161 cg: cg,
1124- color : color ,
1162+ output : output ,
11251163 externs: externs,
11261164 crate_name: crate_name,
11271165 alt_std_name: None ,
0 commit comments