Add an --output option for specifying an error emitter

This commit is contained in:
Nick Cameron
2015-12-31 16:50:06 +13:00
parent acfccc515b
commit fd46c78f8f
12 changed files with 135 additions and 81 deletions

View File

@@ -28,7 +28,7 @@ use self::TargetLint::*;
use dep_graph::DepNode; use dep_graph::DepNode;
use middle::privacy::AccessLevels; use middle::privacy::AccessLevels;
use middle::ty; use middle::ty;
use session::{early_error, Session}; use session::{config, early_error, Session};
use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass}; use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass};
use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject};
use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid}; use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid};
@@ -37,11 +37,12 @@ use util::nodemap::FnvHashMap;
use std::cell::RefCell; use std::cell::RefCell;
use std::cmp; use std::cmp;
use std::default::Default as StdDefault;
use std::mem; use std::mem;
use syntax::ast_util::{self, IdVisitingOperation}; use syntax::ast_util::{self, IdVisitingOperation};
use syntax::attr::{self, AttrMetaMethods}; use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::errors::{self, DiagnosticBuilder}; use syntax::errors::DiagnosticBuilder;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use syntax::ast; use syntax::ast;
use syntax::attr::ThinAttributesExt; use syntax::attr::ThinAttributesExt;
@@ -168,7 +169,7 @@ impl LintStore {
match (sess, from_plugin) { match (sess, from_plugin) {
// We load builtin lints first, so a duplicate is a compiler bug. // We load builtin lints first, so a duplicate is a compiler bug.
// Use early_error when handling -W help with no crate. // Use early_error when handling -W help with no crate.
(None, _) => early_error(errors::ColorConfig::Auto, &msg[..]), (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]),
(Some(sess), false) => sess.bug(&msg[..]), (Some(sess), false) => sess.bug(&msg[..]),
// A duplicate name from a plugin is a user error. // A duplicate name from a plugin is a user error.
@@ -192,7 +193,7 @@ impl LintStore {
match (sess, from_plugin) { match (sess, from_plugin) {
// We load builtin lints first, so a duplicate is a compiler bug. // We load builtin lints first, so a duplicate is a compiler bug.
// Use early_error when handling -W help with no crate. // Use early_error when handling -W help with no crate.
(None, _) => early_error(errors::ColorConfig::Auto, &msg[..]), (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]),
(Some(sess), false) => sess.bug(&msg[..]), (Some(sess), false) => sess.bug(&msg[..]),
// A duplicate name from a plugin is a user error. // A duplicate name from a plugin is a user error.

View File

@@ -14,7 +14,6 @@
pub use self::EntryFnType::*; pub use self::EntryFnType::*;
pub use self::CrateType::*; pub use self::CrateType::*;
pub use self::Passes::*; pub use self::Passes::*;
pub use self::OptLevel::*;
pub use self::DebugInfoLevel::*; pub use self::DebugInfoLevel::*;
use session::{early_error, early_warn, Session}; use session::{early_error, early_warn, Session};
@@ -71,6 +70,18 @@ pub enum OutputType {
DepInfo, DepInfo,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorOutputType {
Tty(ColorConfig),
Json,
}
impl Default for ErrorOutputType {
fn default() -> ErrorOutputType {
ErrorOutputType::Tty(ColorConfig::Auto)
}
}
impl OutputType { impl OutputType {
fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool { fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
match *self { match *self {
@@ -124,6 +135,7 @@ pub struct Options {
pub test: bool, pub test: bool,
pub parse_only: bool, pub parse_only: bool,
pub no_trans: bool, pub no_trans: bool,
pub output: ErrorOutputType,
pub treat_err_as_bug: bool, pub treat_err_as_bug: bool,
pub incremental_compilation: bool, pub incremental_compilation: bool,
pub dump_dep_graph: bool, pub dump_dep_graph: bool,
@@ -131,7 +143,6 @@ pub struct Options {
pub debugging_opts: DebuggingOptions, pub debugging_opts: DebuggingOptions,
pub prints: Vec<PrintRequest>, pub prints: Vec<PrintRequest>,
pub cg: CodegenOptions, pub cg: CodegenOptions,
pub color: ColorConfig,
pub externs: HashMap<String, Vec<String>>, pub externs: HashMap<String, Vec<String>>,
pub crate_name: Option<String>, pub crate_name: Option<String>,
/// An optional name to use as the crate for std during std injection, /// An optional name to use as the crate for std during std injection,
@@ -221,7 +232,7 @@ pub fn basic_options() -> Options {
Options { Options {
crate_types: Vec::new(), crate_types: Vec::new(),
gc: false, gc: false,
optimize: No, optimize: OptLevel::No,
debuginfo: NoDebugInfo, debuginfo: NoDebugInfo,
lint_opts: Vec::new(), lint_opts: Vec::new(),
lint_cap: None, lint_cap: None,
@@ -241,7 +252,12 @@ pub fn basic_options() -> Options {
debugging_opts: basic_debugging_options(), debugging_opts: basic_debugging_options(),
prints: Vec::new(), prints: Vec::new(),
cg: basic_codegen_options(), cg: basic_codegen_options(),
<<<<<<< HEAD
color: ColorConfig::Auto, color: ColorConfig::Auto,
=======
output: ErrorOutputType::default(),
show_span: None,
>>>>>>> Add an --output option for specifying an error emitter
externs: HashMap::new(), externs: HashMap::new(),
crate_name: None, crate_name: None,
alt_std_name: None, alt_std_name: None,
@@ -308,7 +324,7 @@ macro_rules! options {
$struct_name { $($opt: $init),* } $struct_name { $($opt: $init),* }
} }
pub fn $buildfn(matches: &getopts::Matches, color: ColorConfig) -> $struct_name pub fn $buildfn(matches: &getopts::Matches, output: ErrorOutputType) -> $struct_name
{ {
let mut op = $defaultfn(); let mut op = $defaultfn();
for option in matches.opt_strs($prefix) { for option in matches.opt_strs($prefix) {
@@ -322,17 +338,17 @@ macro_rules! options {
if !setter(&mut op, value) { if !setter(&mut op, value) {
match (value, opt_type_desc) { match (value, opt_type_desc) {
(Some(..), None) => { (Some(..), None) => {
early_error(color, &format!("{} option `{}` takes no \ early_error(output, &format!("{} option `{}` takes no \
value", $outputname, key)) value", $outputname, key))
} }
(None, Some(type_desc)) => { (None, Some(type_desc)) => {
early_error(color, &format!("{0} option `{1}` requires \ early_error(output, &format!("{0} option `{1}` requires \
{2} ({3} {1}=<value>)", {2} ({3} {1}=<value>)",
$outputname, key, $outputname, key,
type_desc, $prefix)) type_desc, $prefix))
} }
(Some(value), Some(type_desc)) => { (Some(value), Some(type_desc)) => {
early_error(color, &format!("incorrect value `{}` for {} \ early_error(output, &format!("incorrect value `{}` for {} \
option `{}` - {} was expected", option `{}` - {} was expected",
value, $outputname, value, $outputname,
key, type_desc)) key, type_desc))
@@ -344,7 +360,7 @@ macro_rules! options {
break; break;
} }
if !found { if !found {
early_error(color, &format!("unknown {} option: `{}`", early_error(output, &format!("unknown {} option: `{}`",
$outputname, key)); $outputname, key));
} }
} }
@@ -863,6 +879,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
"NAME=PATH"), "NAME=PATH"),
opt::opt("", "sysroot", "Override the system root", "PATH"), opt::opt("", "sysroot", "Override the system root", "PATH"),
opt::multi("Z", "", "Set internal debugging options", "FLAG"), opt::multi("Z", "", "Set internal debugging options", "FLAG"),
opt::opt_u("", "output", "How errors and other mesasges are produced", "tty|json"),
opt::opt("", "color", "Configure coloring of output: opt::opt("", "color", "Configure coloring of output:
auto = colorize, if output goes to a tty (default); auto = colorize, if output goes to a tty (default);
always = always colorize output; always = always colorize output;
@@ -905,15 +922,36 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
None => ColorConfig::Auto, None => ColorConfig::Auto,
Some(arg) => { Some(arg) => {
early_error(ColorConfig::Auto, &format!("argument for --color must be auto, always \ early_error(ErrorOutputType::default(), &format!("argument for --color must be auto, \
or never (instead was `{}`)", always or never (instead was `{}`)",
arg)) arg))
} }
}; };
// We need the opts_present check because the driver will send us Matches
// with only stable options if no unstable options are used. Since output is
// unstable, it will not be present. We have to use opts_present not
// opt_present because the latter will panic.
let output = if matches.opts_present(&["output".to_owned()]) {
match matches.opt_str("output").as_ref().map(|s| &s[..]) {
Some("tty") => ErrorOutputType::Tty(color),
Some("json") => ErrorOutputType::Json,
None => ErrorOutputType::default(),
Some(arg) => {
early_error(ErrorOutputType::default(), &format!("argument for --output must be tty or \
json (instead was `{}`)",
arg))
}
}
} else {
ErrorOutputType::default()
};
let unparsed_crate_types = matches.opt_strs("crate-type"); let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types) let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(color, &e[..])); .unwrap_or_else(|e| early_error(output, &e[..]));
let mut lint_opts = vec!(); let mut lint_opts = vec!();
let mut describe_lints = false; let mut describe_lints = false;
@@ -930,11 +968,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let lint_cap = matches.opt_str("cap-lints").map(|cap| { let lint_cap = matches.opt_str("cap-lints").map(|cap| {
lint::Level::from_str(&cap).unwrap_or_else(|| { lint::Level::from_str(&cap).unwrap_or_else(|| {
early_error(color, &format!("unknown lint level: `{}`", cap)) early_error(output, &format!("unknown lint level: `{}`", cap))
}) })
}); });
let debugging_opts = build_debugging_options(matches, color); let debugging_opts = build_debugging_options(matches, output);
let parse_only = debugging_opts.parse_only; let parse_only = debugging_opts.parse_only;
let no_trans = debugging_opts.no_trans; let no_trans = debugging_opts.no_trans;
@@ -960,7 +998,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"link" => OutputType::Exe, "link" => OutputType::Exe,
"dep-info" => OutputType::DepInfo, "dep-info" => OutputType::DepInfo,
part => { part => {
early_error(color, &format!("unknown emission type: `{}`", early_error(output, &format!("unknown emission type: `{}`",
part)) part))
} }
}; };
@@ -973,7 +1011,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
output_types.insert(OutputType::Exe, None); output_types.insert(OutputType::Exe, None);
} }
let mut cg = build_codegen_options(matches, color); let mut cg = build_codegen_options(matches, output);
// Issue #30063: if user requests llvm-related output to one // Issue #30063: if user requests llvm-related output to one
// particular path, disable codegen-units. // particular path, disable codegen-units.
@@ -985,11 +1023,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}).collect(); }).collect();
if !incompatible.is_empty() { if !incompatible.is_empty() {
for ot in &incompatible { for ot in &incompatible {
early_warn(color, &format!("--emit={} with -o incompatible with \ early_warn(output, &format!("--emit={} with -o incompatible with \
-C codegen-units=N for N > 1", -C codegen-units=N for N > 1",
ot.shorthand())); ot.shorthand()));
} }
early_warn(color, "resetting to default -C codegen-units=1"); early_warn(output, "resetting to default -C codegen-units=1");
cg.codegen_units = 1; cg.codegen_units = 1;
} }
} }
@@ -1002,29 +1040,29 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let opt_level = { let opt_level = {
if matches.opt_present("O") { if matches.opt_present("O") {
if cg.opt_level.is_some() { if cg.opt_level.is_some() {
early_error(color, "-O and -C opt-level both provided"); early_error(output, "-O and -C opt-level both provided");
} }
Default OptLevel::Default
} else { } else {
match cg.opt_level { match cg.opt_level {
None => No, None => OptLevel::No,
Some(0) => No, Some(0) => OptLevel::No,
Some(1) => Less, Some(1) => OptLevel::Less,
Some(2) => Default, Some(2) => OptLevel::Default,
Some(3) => Aggressive, Some(3) => OptLevel::Aggressive,
Some(arg) => { Some(arg) => {
early_error(color, &format!("optimization level needs to be \ early_error(output, &format!("optimization level needs to be \
between 0-3 (instead was `{}`)", between 0-3 (instead was `{}`)",
arg)); arg));
} }
} }
} }
}; };
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No); let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
let gc = debugging_opts.gc; let gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") { let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() { if cg.debuginfo.is_some() {
early_error(color, "-g and -C debuginfo both provided"); early_error(output, "-g and -C debuginfo both provided");
} }
FullDebugInfo FullDebugInfo
} else { } else {
@@ -1033,7 +1071,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Some(1) => LimitedDebugInfo, Some(1) => LimitedDebugInfo,
Some(2) => FullDebugInfo, Some(2) => FullDebugInfo,
Some(arg) => { Some(arg) => {
early_error(color, &format!("debug info level needs to be between \ early_error(output, &format!("debug info level needs to be between \
0-2 (instead was `{}`)", 0-2 (instead was `{}`)",
arg)); arg));
} }
@@ -1042,7 +1080,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let mut search_paths = SearchPaths::new(); let mut search_paths = SearchPaths::new();
for s in &matches.opt_strs("L") { for s in &matches.opt_strs("L") {
search_paths.add_path(&s[..], color); search_paths.add_path(&s[..], output);
} }
let libs = matches.opt_strs("l").into_iter().map(|s| { let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -1054,7 +1092,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
(Some(name), "framework") => (name, cstore::NativeFramework), (Some(name), "framework") => (name, cstore::NativeFramework),
(Some(name), "static") => (name, cstore::NativeStatic), (Some(name), "static") => (name, cstore::NativeStatic),
(_, s) => { (_, s) => {
early_error(color, &format!("unknown library kind `{}`, expected \ early_error(output, &format!("unknown library kind `{}`, expected \
one of dylib, framework, or static", one of dylib, framework, or static",
s)); s));
} }
@@ -1071,13 +1109,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
"file-names" => PrintRequest::FileNames, "file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot, "sysroot" => PrintRequest::Sysroot,
req => { req => {
early_error(color, &format!("unknown print request `{}`", req)) early_error(output, &format!("unknown print request `{}`", req))
} }
} }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
if !cg.remark.is_empty() && debuginfo == NoDebugInfo { if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
early_warn(color, "-C remark will not show source locations without \ early_warn(output, "-C remark will not show source locations without \
--debuginfo"); --debuginfo");
} }
@@ -1086,11 +1124,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let mut parts = arg.splitn(2, '='); let mut parts = arg.splitn(2, '=');
let name = match parts.next() { let name = match parts.next() {
Some(s) => s, Some(s) => s,
None => early_error(color, "--extern value must not be empty"), None => early_error(output, "--extern value must not be empty"),
}; };
let location = match parts.next() { let location = match parts.next() {
Some(s) => s, Some(s) => s,
None => early_error(color, "--extern value must be of the format `foo=bar`"), None => early_error(output, "--extern value must be of the format `foo=bar`"),
}; };
externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string()); 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 {
debugging_opts: debugging_opts, debugging_opts: debugging_opts,
prints: prints, prints: prints,
cg: cg, cg: cg,
color: color, output: output,
externs: externs, externs: externs,
crate_name: crate_name, crate_name: crate_name,
alt_std_name: None, alt_std_name: None,

View File

@@ -17,7 +17,8 @@ use util::nodemap::{NodeMap, FnvHashMap};
use syntax::ast::{NodeId, NodeIdAssigner, Name}; use syntax::ast::{NodeId, NodeIdAssigner, Name};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::errors::{self, DiagnosticBuilder}; use syntax::errors::{self, DiagnosticBuilder};
use syntax::errors::emitter::{Emitter, BasicEmitter}; use syntax::errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
use syntax::errors::json::JsonEmitter;
use syntax::diagnostics; use syntax::diagnostics;
use syntax::feature_gate; use syntax::feature_gate;
use syntax::parse; use syntax::parse;
@@ -405,12 +406,19 @@ pub fn build_session(sopts: config::Options,
let treat_err_as_bug = sopts.treat_err_as_bug; let treat_err_as_bug = sopts.treat_err_as_bug;
let codemap = Rc::new(codemap::CodeMap::new()); let codemap = Rc::new(codemap::CodeMap::new());
let emitter: Box<Emitter> = match sopts.output {
config::ErrorOutputType::Tty(color_config) => {
Box::new(EmitterWriter::stderr(color_config, Some(registry), codemap.clone()))
}
config::ErrorOutputType::Json => {
Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
}
};
let diagnostic_handler = let diagnostic_handler =
errors::Handler::new(sopts.color, errors::Handler::with_emitter(can_print_warnings,
Some(registry),
can_print_warnings,
treat_err_as_bug, treat_err_as_bug,
codemap.clone()); emitter);
build_session_(sopts, local_crate_source_file, diagnostic_handler, codemap, cstore) build_session_(sopts, local_crate_source_file, diagnostic_handler, codemap, cstore)
} }
@@ -473,13 +481,19 @@ pub fn build_session_(sopts: config::Options,
sess sess
} }
pub fn early_error(color: errors::ColorConfig, msg: &str) -> ! { pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
let mut emitter = BasicEmitter::stderr(color); let mut emitter: Box<Emitter> = match output {
config::ErrorOutputType::Tty(color_config) => Box::new(BasicEmitter::stderr(color_config)),
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
emitter.emit(None, msg, None, errors::Level::Fatal); emitter.emit(None, msg, None, errors::Level::Fatal);
panic!(errors::FatalError); panic!(errors::FatalError);
} }
pub fn early_warn(color: errors::ColorConfig, msg: &str) { pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
let mut emitter = BasicEmitter::stderr(color); let mut emitter: Box<Emitter> = match output {
config::ErrorOutputType::Tty(color_config) => Box::new(BasicEmitter::stderr(color_config)),
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
emitter.emit(None, msg, None, errors::Level::Warning); emitter.emit(None, msg, None, errors::Level::Warning);
} }

View File

@@ -10,8 +10,7 @@
use std::slice; use std::slice;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use session::early_error; use session::{early_error, config};
use syntax::errors;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SearchPaths { pub struct SearchPaths {
@@ -38,7 +37,7 @@ impl SearchPaths {
SearchPaths { paths: Vec::new() } SearchPaths { paths: Vec::new() }
} }
pub fn add_path(&mut self, path: &str, color: errors::ColorConfig) { pub fn add_path(&mut self, path: &str, output: config::ErrorOutputType) {
let (kind, path) = if path.starts_with("native=") { let (kind, path) = if path.starts_with("native=") {
(PathKind::Native, &path["native=".len()..]) (PathKind::Native, &path["native=".len()..])
} else if path.starts_with("crate=") { } else if path.starts_with("crate=") {
@@ -53,7 +52,7 @@ impl SearchPaths {
(PathKind::All, path) (PathKind::All, path)
}; };
if path.is_empty() { if path.is_empty() {
early_error(color, "empty search path given via `-L`"); early_error(output, "empty search path given via `-L`");
} }
self.paths.push((kind, PathBuf::from(path))); self.paths.push((kind, PathBuf::from(path)));
} }

View File

@@ -62,7 +62,7 @@ use rustc_resolve as resolve;
use rustc_trans::back::link; use rustc_trans::back::link;
use rustc_trans::save; use rustc_trans::save;
use rustc::session::{config, Session, build_session}; use rustc::session::{config, Session, build_session};
use rustc::session::config::{Input, PrintRequest, OutputType}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::middle::cstore::CrateStore; use rustc::middle::cstore::CrateStore;
use rustc::lint::Lint; use rustc::lint::Lint;
use rustc::lint; use rustc::lint;
@@ -72,6 +72,7 @@ use rustc::util::common::time;
use std::cmp::max; use std::cmp::max;
use std::cmp::Ordering::Equal; use std::cmp::Ordering::Equal;
use std::default::Default;
use std::env; use std::env;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::iter::repeat; use std::iter::repeat;
@@ -126,7 +127,7 @@ pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>) {
let descriptions = diagnostics_registry(); let descriptions = diagnostics_registry();
do_or_return!(callbacks.early_callback(&matches, &descriptions, sopts.color)); do_or_return!(callbacks.early_callback(&matches, &descriptions, sopts.output));
let (odir, ofile) = make_output(&matches); let (odir, ofile) = make_output(&matches);
let (input, input_file_path) = match make_input(&matches.free) { let (input, input_file_path) = match make_input(&matches.free) {
@@ -214,7 +215,7 @@ pub trait CompilerCalls<'a> {
fn early_callback(&mut self, fn early_callback(&mut self,
_: &getopts::Matches, _: &getopts::Matches,
_: &diagnostics::registry::Registry, _: &diagnostics::registry::Registry,
_: errors::ColorConfig) _: ErrorOutputType)
-> Compilation { -> Compilation {
Compilation::Continue Compilation::Continue
} }
@@ -290,7 +291,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
fn early_callback(&mut self, fn early_callback(&mut self,
matches: &getopts::Matches, matches: &getopts::Matches,
descriptions: &diagnostics::registry::Registry, descriptions: &diagnostics::registry::Registry,
color: errors::ColorConfig) output: ErrorOutputType)
-> Compilation { -> Compilation {
match matches.opt_str("explain") { match matches.opt_str("explain") {
Some(ref code) => { Some(ref code) => {
@@ -305,7 +306,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
print!("{}", &description[1..]); print!("{}", &description[1..]);
} }
None => { None => {
early_error(color, &format!("no extended information for {}", code)); early_error(output, &format!("no extended information for {}", code));
} }
} }
return Compilation::Stop; return Compilation::Stop;
@@ -339,10 +340,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
if should_stop == Compilation::Stop { if should_stop == Compilation::Stop {
return None; return None;
} }
early_error(sopts.color, "no input filename given"); early_error(sopts.output, "no input filename given");
} }
1 => panic!("make_input should have provided valid inputs"), 1 => panic!("make_input should have provided valid inputs"),
_ => early_error(sopts.color, "multiple input filenames provided"), _ => early_error(sopts.output, "multiple input filenames provided"),
} }
None None
@@ -432,7 +433,7 @@ impl RustcDefaultCalls {
println!("{}", String::from_utf8(v).unwrap()); println!("{}", String::from_utf8(v).unwrap());
} }
&Input::Str(_) => { &Input::Str(_) => {
early_error(sess.opts.color, "cannot list metadata for stdin"); early_error(ErrorOutputType::default(), "cannot list metadata for stdin");
} }
} }
return Compilation::Stop; return Compilation::Stop;
@@ -459,7 +460,7 @@ impl RustcDefaultCalls {
PrintRequest::CrateName => { PrintRequest::CrateName => {
let input = match input { let input = match input {
Some(input) => input, Some(input) => input,
None => early_error(sess.opts.color, "no input file provided"), None => early_error(ErrorOutputType::default(), "no input file provided"),
}; };
let attrs = attrs.as_ref().unwrap(); let attrs = attrs.as_ref().unwrap();
let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess); let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess);
@@ -752,7 +753,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
&opt.opt_group.short_name &opt.opt_group.short_name
}; };
if m.opt_present(opt_name) { if m.opt_present(opt_name) {
early_error(errors::ColorConfig::Auto, early_error(ErrorOutputType::default(),
&format!("use of unstable option '{}' requires -Z \ &format!("use of unstable option '{}' requires -Z \
unstable-options", unstable-options",
opt_name)); opt_name));
@@ -761,7 +762,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
} }
m m
} }
Err(f) => early_error(errors::ColorConfig::Auto, &f.to_string()), Err(f) => early_error(ErrorOutputType::default(), &f.to_string()),
} }
} }

View File

@@ -149,8 +149,8 @@ impl<'a> Linker for GnuLinker<'a> {
// GNU-style linkers support optimization with -O. GNU ld doesn't // GNU-style linkers support optimization with -O. GNU ld doesn't
// need a numeric argument, but other linkers do. // need a numeric argument, but other linkers do.
if self.sess.opts.optimize == config::Default || if self.sess.opts.optimize == config::OptLevel::Default ||
self.sess.opts.optimize == config::Aggressive { self.sess.opts.optimize == config::OptLevel::Aggressive {
self.cmd.arg("-Wl,-O1"); self.cmd.arg("-Wl,-O1");
} }
} }

View File

@@ -144,10 +144,10 @@ fn target_feature(sess: &Session) -> String {
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel { fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
match optimize { match optimize {
config::No => llvm::CodeGenLevelNone, config::OptLevel::No => llvm::CodeGenLevelNone,
config::Less => llvm::CodeGenLevelLess, config::OptLevel::Less => llvm::CodeGenLevelLess,
config::Default => llvm::CodeGenLevelDefault, config::OptLevel::Default => llvm::CodeGenLevelDefault,
config::Aggressive => llvm::CodeGenLevelAggressive, config::OptLevel::Aggressive => llvm::CodeGenLevelAggressive,
} }
} }
@@ -303,13 +303,13 @@ impl ModuleConfig {
// slp vectorization at O3. Otherwise configure other optimization aspects // slp vectorization at O3. Otherwise configure other optimization aspects
// of this pass manager builder. // of this pass manager builder.
self.vectorize_loop = !sess.opts.cg.no_vectorize_loops && self.vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
(sess.opts.optimize == config::Default || (sess.opts.optimize == config::OptLevel::Default ||
sess.opts.optimize == config::Aggressive); sess.opts.optimize == config::OptLevel::Aggressive);
self.vectorize_slp = !sess.opts.cg.no_vectorize_slp && self.vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
sess.opts.optimize == config::Aggressive; sess.opts.optimize == config::OptLevel::Aggressive;
self.merge_functions = sess.opts.optimize == config::Default || self.merge_functions = sess.opts.optimize == config::OptLevel::Default ||
sess.opts.optimize == config::Aggressive; sess.opts.optimize == config::OptLevel::Aggressive;
} }
} }

View File

@@ -1163,7 +1163,7 @@ fn core_lifetime_emit<'blk, 'tcx, F>(ccx: &'blk CrateContext<'blk, 'tcx>,
emit: F) emit: F)
where F: FnOnce(&'blk CrateContext<'blk, 'tcx>, machine::llsize, ValueRef) where F: FnOnce(&'blk CrateContext<'blk, 'tcx>, machine::llsize, ValueRef)
{ {
if ccx.sess().opts.optimize == config::No { if ccx.sess().opts.optimize == config::OptLevel::No {
return; return;
} }

View File

@@ -1020,7 +1020,7 @@ pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
compile_unit_name, compile_unit_name,
work_dir.as_ptr(), work_dir.as_ptr(),
producer.as_ptr(), producer.as_ptr(),
cx.sess().opts.optimize != config::No, cx.sess().opts.optimize != config::OptLevel::No,
flags.as_ptr() as *const _, flags.as_ptr() as *const _,
0, 0,
split_name.as_ptr() as *const _) split_name.as_ptr() as *const _)

View File

@@ -383,7 +383,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
true, true,
scope_line as c_uint, scope_line as c_uint,
FlagPrototyped as c_uint, FlagPrototyped as c_uint,
cx.sess().opts.optimize != config::No, cx.sess().opts.optimize != config::OptLevel::No,
llfn, llfn,
template_parameters, template_parameters,
ptr::null_mut()) ptr::null_mut())
@@ -596,7 +596,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
file_metadata, file_metadata,
loc.line as c_uint, loc.line as c_uint,
type_metadata, type_metadata,
cx.sess().opts.optimize != config::No, cx.sess().opts.optimize != config::OptLevel::No,
0, 0,
address_operations.as_ptr(), address_operations.as_ptr(),
address_operations.len() as c_uint, address_operations.len() as c_uint,

View File

@@ -43,7 +43,7 @@ pub trait Emitter {
/// maximum number of lines we will print for each error; arbitrary. /// maximum number of lines we will print for each error; arbitrary.
const MAX_LINES: usize = 6; const MAX_LINES: usize = 6;
#[derive(Clone, Copy)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ColorConfig { pub enum ColorConfig {
Auto, Auto,
Always, Always,

View File

@@ -276,6 +276,7 @@ pub struct Handler {
} }
impl Handler { impl Handler {
// TODO remove
pub fn new(color_config: ColorConfig, pub fn new(color_config: ColorConfig,
registry: Option<diagnostics::registry::Registry>, registry: Option<diagnostics::registry::Registry>,
can_emit_warnings: bool, can_emit_warnings: bool,