Skip to content

Respect --color when printing early errors #27983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 31, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use syntax::codemap::Span;
use syntax::visit::{Visitor, FnKind};
use syntax::parse::token::InternedString;
use syntax::{ast, ast_util, visit};
use syntax::diagnostic;

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

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

// A duplicate name from a plugin is a user error.
Expand Down
100 changes: 50 additions & 50 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ macro_rules! options {
$struct_name { $($opt: $init),* }
}

pub fn $buildfn(matches: &getopts::Matches) -> $struct_name
pub fn $buildfn(matches: &getopts::Matches, color: ColorConfig) -> $struct_name
{
let mut op = $defaultfn();
for option in matches.opt_strs($prefix) {
Expand All @@ -302,20 +302,20 @@ macro_rules! options {
if !setter(&mut op, value) {
match (value, opt_type_desc) {
(Some(..), None) => {
early_error(&format!("{} option `{}` takes no \
value", $outputname, key))
early_error(color, &format!("{} option `{}` takes no \
value", $outputname, key))
}
(None, Some(type_desc)) => {
early_error(&format!("{0} option `{1}` requires \
{2} ({3} {1}=<value>)",
$outputname, key,
type_desc, $prefix))
early_error(color, &format!("{0} option `{1}` requires \
{2} ({3} {1}=<value>)",
$outputname, key,
type_desc, $prefix))
}
(Some(value), Some(type_desc)) => {
early_error(&format!("incorrect value `{}` for {} \
option `{}` - {} was expected",
value, $outputname,
key, type_desc))
early_error(color, &format!("incorrect value `{}` for {} \
option `{}` - {} was expected",
value, $outputname,
key, type_desc))
}
(None, None) => unreachable!()
}
Expand All @@ -324,8 +324,8 @@ macro_rules! options {
break;
}
if !found {
early_error(&format!("unknown {} option: `{}`",
$outputname, key));
early_error(color, &format!("unknown {} option: `{}`",
$outputname, key));
}
}
return op;
Expand Down Expand Up @@ -850,9 +850,23 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
}

pub fn build_session_options(matches: &getopts::Matches) -> Options {
let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
Some("auto") => Auto,
Some("always") => Always,
Some("never") => Never,

None => Auto,

Some(arg) => {
early_error(Auto, &format!("argument for --color must be auto, always \
or never (instead was `{}`)",
arg))
}
};

let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(&e[..]));
.unwrap_or_else(|e| early_error(color, &e[..]));

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

let lint_cap = matches.opt_str("cap-lints").map(|cap| {
lint::Level::from_str(&cap).unwrap_or_else(|| {
early_error(&format!("unknown lint level: `{}`", cap))
early_error(color, &format!("unknown lint level: `{}`", cap))
})
});

let debugging_opts = build_debugging_options(matches);
let debugging_opts = build_debugging_options(matches, color);

let parse_only = debugging_opts.parse_only;
let no_trans = debugging_opts.no_trans;
Expand All @@ -897,8 +911,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"link" => OutputTypeExe,
"dep-info" => OutputTypeDepInfo,
_ => {
early_error(&format!("unknown emission type: `{}`",
part))
early_error(color, &format!("unknown emission type: `{}`",
part))
}
};
output_types.push(output_type)
Expand All @@ -911,15 +925,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
output_types.push(OutputTypeExe);
}

let cg = build_codegen_options(matches);
let cg = build_codegen_options(matches, color);

let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target = matches.opt_str("target").unwrap_or(
host_triple().to_string());
let opt_level = {
if matches.opt_present("O") {
if cg.opt_level.is_some() {
early_error("-O and -C opt-level both provided");
early_error(color, "-O and -C opt-level both provided");
}
Default
} else {
Expand All @@ -930,9 +944,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(2) => Default,
Some(3) => Aggressive,
Some(arg) => {
early_error(&format!("optimization level needs to be \
between 0-3 (instead was `{}`)",
arg));
early_error(color, &format!("optimization level needs to be \
between 0-3 (instead was `{}`)",
arg));
}
}
}
Expand All @@ -941,7 +955,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() {
early_error("-g and -C debuginfo both provided");
early_error(color, "-g and -C debuginfo both provided");
}
FullDebugInfo
} else {
Expand All @@ -950,16 +964,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(1) => LimitedDebugInfo,
Some(2) => FullDebugInfo,
Some(arg) => {
early_error(&format!("debug info level needs to be between \
0-2 (instead was `{}`)",
arg));
early_error(color, &format!("debug info level needs to be between \
0-2 (instead was `{}`)",
arg));
}
}
};

let mut search_paths = SearchPaths::new();
for s in &matches.opt_strs("L") {
search_paths.add_path(&s[..]);
search_paths.add_path(&s[..], color);
}

let libs = matches.opt_strs("l").into_iter().map(|s| {
Expand All @@ -971,9 +985,9 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
(Some(name), "framework") => (name, cstore::NativeFramework),
(Some(name), "static") => (name, cstore::NativeStatic),
(_, s) => {
early_error(&format!("unknown library kind `{}`, expected \
one of dylib, framework, or static",
s));
early_error(color, &format!("unknown library kind `{}`, expected \
one of dylib, framework, or static",
s));
}
};
(name.to_string(), kind)
Expand All @@ -989,40 +1003,26 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot,
req => {
early_error(&format!("unknown print request `{}`", req))
early_error(color, &format!("unknown print request `{}`", req))
}
}
}).collect::<Vec<_>>();

if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
early_warn("-C remark will not show source locations without \
--debuginfo");
early_warn(color, "-C remark will not show source locations without \
--debuginfo");
}

let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
Some("auto") => Auto,
Some("always") => Always,
Some("never") => Never,

None => Auto,

Some(arg) => {
early_error(&format!("argument for --color must be auto, always \
or never (instead was `{}`)",
arg))
}
};

let mut externs = HashMap::new();
for arg in &matches.opt_strs("extern") {
let mut parts = arg.splitn(2, '=');
let name = match parts.next() {
Some(s) => s,
None => early_error("--extern value must not be empty"),
None => early_error(color, "--extern value must not be empty"),
};
let location = match parts.next() {
Some(s) => s,
None => early_error("--extern value must be of the format `foo=bar`"),
None => early_error(color, "--extern value must be of the format `foo=bar`"),
};

externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,13 +473,13 @@ pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
diagnostic::expect(sess.diagnostic(), opt, msg)
}

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

pub fn early_warn(msg: &str) {
let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
pub fn early_warn(color: diagnostic::ColorConfig, msg: &str) {
let mut emitter = diagnostic::EmitterWriter::stderr(color, None);
emitter.emit(None, msg, None, diagnostic::Warning);
}
5 changes: 3 additions & 2 deletions src/librustc/session/search_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::slice;
use std::path::{Path, PathBuf};
use session::early_error;
use syntax::diagnostic;

#[derive(Clone, Debug)]
pub struct SearchPaths {
Expand All @@ -37,7 +38,7 @@ impl SearchPaths {
SearchPaths { paths: Vec::new() }
}

pub fn add_path(&mut self, path: &str) {
pub fn add_path(&mut self, path: &str, color: diagnostic::ColorConfig) {
let (kind, path) = if path.starts_with("native=") {
(PathKind::Native, &path["native=".len()..])
} else if path.starts_with("crate=") {
Expand All @@ -52,7 +53,7 @@ impl SearchPaths {
(PathKind::All, path)
};
if path.is_empty() {
early_error("empty search path given via `-L`");
early_error(color, "empty search path given via `-L`");
}
self.paths.push((kind, PathBuf::from(path)));
}
Expand Down
29 changes: 16 additions & 13 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ pub fn run_compiler<'a>(args: &[String],
None => return
};

let descriptions = diagnostics_registry();
let sopts = config::build_session_options(&matches);

do_or_return!(callbacks.early_callback(&matches, &descriptions));
let descriptions = diagnostics_registry();

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

let (odir, ofile) = make_output(&matches);
let (input, input_file_path) = match make_input(&matches.free) {
Expand Down Expand Up @@ -205,7 +205,8 @@ pub trait CompilerCalls<'a> {
// else (e.g., selecting input and output).
fn early_callback(&mut self,
_: &getopts::Matches,
_: &diagnostics::registry::Registry)
_: &diagnostics::registry::Registry,
_: diagnostic::ColorConfig)
-> Compilation {
Compilation::Continue
}
Expand Down Expand Up @@ -277,7 +278,8 @@ pub struct RustcDefaultCalls;
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
fn early_callback(&mut self,
matches: &getopts::Matches,
descriptions: &diagnostics::registry::Registry)
descriptions: &diagnostics::registry::Registry,
color: diagnostic::ColorConfig)
-> Compilation {
match matches.opt_str("explain") {
Some(ref code) => {
Expand All @@ -287,7 +289,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
print!("{}", &description[1..]);
}
None => {
early_error(&format!("no extended information for {}", code));
early_error(color, &format!("no extended information for {}", code));
}
}
return Compilation::Stop;
Expand Down Expand Up @@ -319,10 +321,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
if should_stop == Compilation::Stop {
return None;
}
early_error("no input filename given");
early_error(sopts.color, "no input filename given");
}
1 => panic!("make_input should have provided valid inputs"),
_ => early_error("multiple input filenames provided")
_ => early_error(sopts.color, "multiple input filenames provided")
}

None
Expand Down Expand Up @@ -414,7 +416,7 @@ impl RustcDefaultCalls {
println!("{}", String::from_utf8(v).unwrap());
}
&Input::Str(_) => {
early_error("cannot list metadata for stdin");
early_error(sess.opts.color, "cannot list metadata for stdin");
}
}
return Compilation::Stop;
Expand All @@ -441,7 +443,7 @@ impl RustcDefaultCalls {
PrintRequest::CrateName => {
let input = match input {
Some(input) => input,
None => early_error("no input file provided"),
None => early_error(sess.opts.color, "no input file provided"),
};
let attrs = attrs.as_ref().unwrap();
let t_outputs = driver::build_output_filenames(input,
Expand Down Expand Up @@ -701,14 +703,15 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
&opt.opt_group.short_name
};
if m.opt_present(opt_name) {
early_error(&format!("use of unstable option '{}' requires \
-Z unstable-options", opt_name));
early_error(diagnostic::Auto, &format!("use of unstable option '{}' \
requires -Z unstable-options",
opt_name));
}
}
}
m
}
Err(f) => early_error(&f.to_string())
Err(f) => early_error(diagnostic::Auto, &f.to_string())
}
}

Expand Down
Loading