Skip to content

Commit fe9cef7

Browse files
committed
Auto merge of #27983 - barosl:respect-color, r=nrc
Currently, `early_error` and `early_warn` in `librustc::session` always use `ColorConfig::Auto`. Modify them to follow the color configuration set by the `--color` option. As colored output is also printed during the early stage, parsing the `--color` option should be done as early as possible. However, there are still some cases when the output needs to be colored before knowing the exact color settings. In these cases, it will be defaulted to `ColorConfig::Auto`, which is the same as before. Fixes #27879.
2 parents 2aa7f97 + 71f39c1 commit fe9cef7

File tree

7 files changed

+82
-75
lines changed

7 files changed

+82
-75
lines changed

src/librustc/lint/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use syntax::codemap::Span;
4343
use syntax::visit::{Visitor, FnKind};
4444
use syntax::parse::token::InternedString;
4545
use syntax::{ast, ast_util, visit};
46+
use syntax::diagnostic;
4647

4748
/// Information about the registered lints.
4849
///
@@ -141,7 +142,7 @@ impl LintStore {
141142
match (sess, from_plugin) {
142143
// We load builtin lints first, so a duplicate is a compiler bug.
143144
// Use early_error when handling -W help with no crate.
144-
(None, _) => early_error(&msg[..]),
145+
(None, _) => early_error(diagnostic::Auto, &msg[..]),
145146
(Some(sess), false) => sess.bug(&msg[..]),
146147

147148
// A duplicate name from a plugin is a user error.
@@ -166,7 +167,7 @@ impl LintStore {
166167
match (sess, from_plugin) {
167168
// We load builtin lints first, so a duplicate is a compiler bug.
168169
// Use early_error when handling -W help with no crate.
169-
(None, _) => early_error(&msg[..]),
170+
(None, _) => early_error(diagnostic::Auto, &msg[..]),
170171
(Some(sess), false) => sess.bug(&msg[..]),
171172

172173
// A duplicate name from a plugin is a user error.

src/librustc/session/config.rs

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ macro_rules! options {
288288
$struct_name { $($opt: $init),* }
289289
}
290290

291-
pub fn $buildfn(matches: &getopts::Matches) -> $struct_name
291+
pub fn $buildfn(matches: &getopts::Matches, color: ColorConfig) -> $struct_name
292292
{
293293
let mut op = $defaultfn();
294294
for option in matches.opt_strs($prefix) {
@@ -302,20 +302,20 @@ macro_rules! options {
302302
if !setter(&mut op, value) {
303303
match (value, opt_type_desc) {
304304
(Some(..), None) => {
305-
early_error(&format!("{} option `{}` takes no \
306-
value", $outputname, key))
305+
early_error(color, &format!("{} option `{}` takes no \
306+
value", $outputname, key))
307307
}
308308
(None, Some(type_desc)) => {
309-
early_error(&format!("{0} option `{1}` requires \
310-
{2} ({3} {1}=<value>)",
311-
$outputname, key,
312-
type_desc, $prefix))
309+
early_error(color, &format!("{0} option `{1}` requires \
310+
{2} ({3} {1}=<value>)",
311+
$outputname, key,
312+
type_desc, $prefix))
313313
}
314314
(Some(value), Some(type_desc)) => {
315-
early_error(&format!("incorrect value `{}` for {} \
316-
option `{}` - {} was expected",
317-
value, $outputname,
318-
key, type_desc))
315+
early_error(color, &format!("incorrect value `{}` for {} \
316+
option `{}` - {} was expected",
317+
value, $outputname,
318+
key, type_desc))
319319
}
320320
(None, None) => unreachable!()
321321
}
@@ -324,8 +324,8 @@ macro_rules! options {
324324
break;
325325
}
326326
if !found {
327-
early_error(&format!("unknown {} option: `{}`",
328-
$outputname, key));
327+
early_error(color, &format!("unknown {} option: `{}`",
328+
$outputname, key));
329329
}
330330
}
331331
return op;
@@ -850,9 +850,23 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
850850
}
851851

852852
pub fn build_session_options(matches: &getopts::Matches) -> Options {
853+
let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
854+
Some("auto") => Auto,
855+
Some("always") => Always,
856+
Some("never") => Never,
857+
858+
None => Auto,
859+
860+
Some(arg) => {
861+
early_error(Auto, &format!("argument for --color must be auto, always \
862+
or never (instead was `{}`)",
863+
arg))
864+
}
865+
};
866+
853867
let unparsed_crate_types = matches.opt_strs("crate-type");
854868
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
855-
.unwrap_or_else(|e| early_error(&e[..]));
869+
.unwrap_or_else(|e| early_error(color, &e[..]));
856870

857871
let mut lint_opts = vec!();
858872
let mut describe_lints = false;
@@ -869,11 +883,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
869883

870884
let lint_cap = matches.opt_str("cap-lints").map(|cap| {
871885
lint::Level::from_str(&cap).unwrap_or_else(|| {
872-
early_error(&format!("unknown lint level: `{}`", cap))
886+
early_error(color, &format!("unknown lint level: `{}`", cap))
873887
})
874888
});
875889

876-
let debugging_opts = build_debugging_options(matches);
890+
let debugging_opts = build_debugging_options(matches, color);
877891

878892
let parse_only = debugging_opts.parse_only;
879893
let no_trans = debugging_opts.no_trans;
@@ -897,8 +911,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
897911
"link" => OutputTypeExe,
898912
"dep-info" => OutputTypeDepInfo,
899913
_ => {
900-
early_error(&format!("unknown emission type: `{}`",
901-
part))
914+
early_error(color, &format!("unknown emission type: `{}`",
915+
part))
902916
}
903917
};
904918
output_types.push(output_type)
@@ -911,15 +925,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
911925
output_types.push(OutputTypeExe);
912926
}
913927

914-
let cg = build_codegen_options(matches);
928+
let cg = build_codegen_options(matches, color);
915929

916930
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
917931
let target = matches.opt_str("target").unwrap_or(
918932
host_triple().to_string());
919933
let opt_level = {
920934
if matches.opt_present("O") {
921935
if cg.opt_level.is_some() {
922-
early_error("-O and -C opt-level both provided");
936+
early_error(color, "-O and -C opt-level both provided");
923937
}
924938
Default
925939
} else {
@@ -930,9 +944,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
930944
Some(2) => Default,
931945
Some(3) => Aggressive,
932946
Some(arg) => {
933-
early_error(&format!("optimization level needs to be \
934-
between 0-3 (instead was `{}`)",
935-
arg));
947+
early_error(color, &format!("optimization level needs to be \
948+
between 0-3 (instead was `{}`)",
949+
arg));
936950
}
937951
}
938952
}
@@ -941,7 +955,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
941955
let gc = debugging_opts.gc;
942956
let debuginfo = if matches.opt_present("g") {
943957
if cg.debuginfo.is_some() {
944-
early_error("-g and -C debuginfo both provided");
958+
early_error(color, "-g and -C debuginfo both provided");
945959
}
946960
FullDebugInfo
947961
} else {
@@ -950,16 +964,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
950964
Some(1) => LimitedDebugInfo,
951965
Some(2) => FullDebugInfo,
952966
Some(arg) => {
953-
early_error(&format!("debug info level needs to be between \
954-
0-2 (instead was `{}`)",
955-
arg));
967+
early_error(color, &format!("debug info level needs to be between \
968+
0-2 (instead was `{}`)",
969+
arg));
956970
}
957971
}
958972
};
959973

960974
let mut search_paths = SearchPaths::new();
961975
for s in &matches.opt_strs("L") {
962-
search_paths.add_path(&s[..]);
976+
search_paths.add_path(&s[..], color);
963977
}
964978

965979
let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -971,9 +985,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
971985
(Some(name), "framework") => (name, cstore::NativeFramework),
972986
(Some(name), "static") => (name, cstore::NativeStatic),
973987
(_, s) => {
974-
early_error(&format!("unknown library kind `{}`, expected \
975-
one of dylib, framework, or static",
976-
s));
988+
early_error(color, &format!("unknown library kind `{}`, expected \
989+
one of dylib, framework, or static",
990+
s));
977991
}
978992
};
979993
(name.to_string(), kind)
@@ -989,40 +1003,26 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
9891003
"file-names" => PrintRequest::FileNames,
9901004
"sysroot" => PrintRequest::Sysroot,
9911005
req => {
992-
early_error(&format!("unknown print request `{}`", req))
1006+
early_error(color, &format!("unknown print request `{}`", req))
9931007
}
9941008
}
9951009
}).collect::<Vec<_>>();
9961010

9971011
if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
998-
early_warn("-C remark will not show source locations without \
999-
--debuginfo");
1012+
early_warn(color, "-C remark will not show source locations without \
1013+
--debuginfo");
10001014
}
10011015

1002-
let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
1003-
Some("auto") => Auto,
1004-
Some("always") => Always,
1005-
Some("never") => Never,
1006-
1007-
None => Auto,
1008-
1009-
Some(arg) => {
1010-
early_error(&format!("argument for --color must be auto, always \
1011-
or never (instead was `{}`)",
1012-
arg))
1013-
}
1014-
};
1015-
10161016
let mut externs = HashMap::new();
10171017
for arg in &matches.opt_strs("extern") {
10181018
let mut parts = arg.splitn(2, '=');
10191019
let name = match parts.next() {
10201020
Some(s) => s,
1021-
None => early_error("--extern value must not be empty"),
1021+
None => early_error(color, "--extern value must not be empty"),
10221022
};
10231023
let location = match parts.next() {
10241024
Some(s) => s,
1025-
None => early_error("--extern value must be of the format `foo=bar`"),
1025+
None => early_error(color, "--extern value must be of the format `foo=bar`"),
10261026
};
10271027

10281028
externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());

src/librustc/session/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,13 +473,13 @@ pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
473473
diagnostic::expect(sess.diagnostic(), opt, msg)
474474
}
475475

476-
pub fn early_error(msg: &str) -> ! {
477-
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
476+
pub fn early_error(color: diagnostic::ColorConfig, msg: &str) -> ! {
477+
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
478478
emitter.emit(None, msg, None, diagnostic::Fatal);
479479
panic!(diagnostic::FatalError);
480480
}
481481

482-
pub fn early_warn(msg: &str) {
483-
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
482+
pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
483+
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
484484
emitter.emit(None, msg, None, diagnostic::Warning);
485485
}

src/librustc/session/search_paths.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::slice;
1212
use std::path::{Path, PathBuf};
1313
use session::early_error;
14+
use syntax::diagnostic;
1415

1516
#[derive(Clone, Debug)]
1617
pub struct SearchPaths {
@@ -37,7 +38,7 @@ impl SearchPaths {
3738
SearchPaths { paths: Vec::new() }
3839
}
3940

40-
pub fn add_path(&mut self, path: &str) {
41+
pub fn add_path(&mut self, path: &str, color: diagnostic::ColorConfig) {
4142
let (kind, path) = if path.starts_with("native=") {
4243
(PathKind::Native, &path["native=".len()..])
4344
} else if path.starts_with("crate=") {
@@ -52,7 +53,7 @@ impl SearchPaths {
5253
(PathKind::All, path)
5354
};
5455
if path.is_empty() {
55-
early_error("empty search path given via `-L`");
56+
early_error(color, "empty search path given via `-L`");
5657
}
5758
self.paths.push((kind, PathBuf::from(path)));
5859
}

src/librustc_driver/lib.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ pub fn run_compiler<'a>(args: &[String],
117117
None => return
118118
};
119119

120-
let descriptions = diagnostics_registry();
120+
let sopts = config::build_session_options(&matches);
121121

122-
do_or_return!(callbacks.early_callback(&matches, &descriptions));
122+
let descriptions = diagnostics_registry();
123123

124-
let sopts = config::build_session_options(&matches);
124+
do_or_return!(callbacks.early_callback(&matches, &descriptions, sopts.color));
125125

126126
let (odir, ofile) = make_output(&matches);
127127
let (input, input_file_path) = match make_input(&matches.free) {
@@ -205,7 +205,8 @@ pub trait CompilerCalls<'a> {
205205
// else (e.g., selecting input and output).
206206
fn early_callback(&mut self,
207207
_: &getopts::Matches,
208-
_: &diagnostics::registry::Registry)
208+
_: &diagnostics::registry::Registry,
209+
_: diagnostic::ColorConfig)
209210
-> Compilation {
210211
Compilation::Continue
211212
}
@@ -277,7 +278,8 @@ pub struct RustcDefaultCalls;
277278
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
278279
fn early_callback(&mut self,
279280
matches: &getopts::Matches,
280-
descriptions: &diagnostics::registry::Registry)
281+
descriptions: &diagnostics::registry::Registry,
282+
color: diagnostic::ColorConfig)
281283
-> Compilation {
282284
match matches.opt_str("explain") {
283285
Some(ref code) => {
@@ -287,7 +289,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
287289
print!("{}", &description[1..]);
288290
}
289291
None => {
290-
early_error(&format!("no extended information for {}", code));
292+
early_error(color, &format!("no extended information for {}", code));
291293
}
292294
}
293295
return Compilation::Stop;
@@ -319,10 +321,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
319321
if should_stop == Compilation::Stop {
320322
return None;
321323
}
322-
early_error("no input filename given");
324+
early_error(sopts.color, "no input filename given");
323325
}
324326
1 => panic!("make_input should have provided valid inputs"),
325-
_ => early_error("multiple input filenames provided")
327+
_ => early_error(sopts.color, "multiple input filenames provided")
326328
}
327329

328330
None
@@ -414,7 +416,7 @@ impl RustcDefaultCalls {
414416
println!("{}", String::from_utf8(v).unwrap());
415417
}
416418
&Input::Str(_) => {
417-
early_error("cannot list metadata for stdin");
419+
early_error(sess.opts.color, "cannot list metadata for stdin");
418420
}
419421
}
420422
return Compilation::Stop;
@@ -441,7 +443,7 @@ impl RustcDefaultCalls {
441443
PrintRequest::CrateName => {
442444
let input = match input {
443445
Some(input) => input,
444-
None => early_error("no input file provided"),
446+
None => early_error(sess.opts.color, "no input file provided"),
445447
};
446448
let attrs = attrs.as_ref().unwrap();
447449
let t_outputs = driver::build_output_filenames(input,
@@ -701,14 +703,15 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
701703
&opt.opt_group.short_name
702704
};
703705
if m.opt_present(opt_name) {
704-
early_error(&format!("use of unstable option '{}' requires \
705-
-Z unstable-options", opt_name));
706+
early_error(diagnostic::Auto, &format!("use of unstable option '{}' \
707+
requires -Z unstable-options",
708+
opt_name));
706709
}
707710
}
708711
}
709712
m
710713
}
711-
Err(f) => early_error(&f.to_string())
714+
Err(f) => early_error(diagnostic::Auto, &f.to_string())
712715
}
713716
}
714717

0 commit comments

Comments
 (0)