}
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
- let mut emitter: Box<Emitter> = match output {
+ let emitter: Box<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config,
None,
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
- emitter.emit(&MultiSpan::new(), msg, None, errors::Level::Fatal);
+ let handler = errors::Handler::with_emitter(true, false, emitter);
+ handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
panic!(errors::FatalError);
}
pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
- let mut emitter: Box<Emitter> = match output {
+ let emitter: Box<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(EmitterWriter::stderr(color_config,
None,
}
config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
};
- emitter.emit(&MultiSpan::new(), msg, None, errors::Level::Warning);
+ let handler = errors::Handler::with_emitter(true, false, emitter);
+ handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
}
// Err(0) means compilation was stopped, but no errors were found.
match session {
Some(sess) => sess.fatal(&abort_msg(err_count)),
None => {
- let mut emitter =
+ let emitter =
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
None,
None,
FormatMode::EnvironmentSelected);
- emitter.emit(&MultiSpan::new(), &abort_msg(err_count), None,
- errors::Level::Fatal);
+ let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
+ handler.emit(&MultiSpan::new(),
+ &abort_msg(err_count),
+ errors::Level::Fatal);
exit_on_err();
}
}
fn check_cfg(sopts: &config::Options,
output: ErrorOutputType) {
- let mut emitter: Box<Emitter> = match output {
+ let emitter: Box<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
Box::new(errors::emitter::EmitterWriter::stderr(color_config,
None,
}
config::ErrorOutputType::Json => Box::new(json::JsonEmitter::basic()),
};
+ let handler = errors::Handler::with_emitter(true, false, emitter);
let mut saw_invalid_predicate = false;
for item in sopts.cfg.iter() {
match item.node {
ast::MetaItemKind::List(ref pred, _) => {
saw_invalid_predicate = true;
- emitter.emit(&MultiSpan::new(),
+ handler.emit(&MultiSpan::new(),
&format!("invalid predicate in --cfg command line argument: `{}`",
pred),
- None,
- errors::Level::Fatal);
+ errors::Level::Fatal);
}
_ => {},
}
if let Err(value) = thread.unwrap().join() {
// Thread panicked without emitting a fatal diagnostic
if !value.is::<errors::FatalError>() {
- let mut emitter =
- errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
+ let emitter =
+ Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
None,
None,
- FormatMode::EnvironmentSelected);
+ FormatMode::EnvironmentSelected));
+ let handler = errors::Handler::with_emitter(true, false, emitter);
// a .span_bug or .bug call has already printed what
// it wants to print.
if !value.is::<errors::ExplicitBug>() {
- emitter.emit(&MultiSpan::new(), "unexpected panic", None, errors::Level::Bug);
+ handler.emit(&MultiSpan::new(),
+ "unexpected panic",
+ errors::Level::Bug);
}
let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}", BUG_REPORT_URL)];
for note in &xs {
- emitter.emit(&MultiSpan::new(), ¬e[..], None, errors::Level::Note)
+ handler.emit(&MultiSpan::new(),
+ ¬e[..],
+ errors::Level::Note);
}
if match env::var_os("RUST_BACKTRACE") {
Some(val) => &val != "0",
None => false,
} {
- emitter.emit(&MultiSpan::new(),
+ handler.emit(&MultiSpan::new(),
"run with `RUST_BACKTRACE=1` for a backtrace",
- None,
errors::Level::Note);
}
/// Emitter trait for emitting errors. Do not implement this directly:
/// implement `CoreEmitter` instead.
pub trait Emitter {
- /// Emit a standalone diagnostic message.
- fn emit(&mut self, span: &MultiSpan, msg: &str, code: Option<&str>, lvl: Level);
-
/// Emit a structured diagnostic.
fn emit_struct(&mut self, db: &DiagnosticBuilder);
}
}
impl<T: CoreEmitter> Emitter for T {
- fn emit(&mut self,
- msp: &MultiSpan,
- msg: &str,
- code: Option<&str>,
- lvl: Level) {
- self.emit_message(&FullSpan(msp.clone()),
- msg,
- code,
- lvl,
- true,
- true);
- }
-
fn emit_struct(&mut self, db: &DiagnosticBuilder) {
let old_school = check_old_skool();
let db_span = FullSpan(db.span.clone());
fn new(handler: &'a Handler,
level: Level,
message: &str) -> DiagnosticBuilder<'a> {
+ DiagnosticBuilder::new_with_code(handler, level, None, message)
+ }
+
+ /// Convenience function for internal use, clients should use one of the
+ /// struct_* methods on Handler.
+ fn new_with_code(handler: &'a Handler,
+ level: Level,
+ code: Option<String>,
+ message: &str) -> DiagnosticBuilder<'a> {
DiagnosticBuilder {
handler: handler,
level: level,
message: message.to_owned(),
- code: None,
+ code: code,
span: MultiSpan::new(),
children: vec![],
}
impl<'a> Drop for DiagnosticBuilder<'a> {
fn drop(&mut self) {
if !panicking() && !self.cancelled() {
- self.handler.emit.borrow_mut().emit(&MultiSpan::new(),
- "Error constructed but not emitted",
- None,
- Bug);
+ let mut db = DiagnosticBuilder::new(self.handler,
+ Bug,
+ "Error constructed but not emitted");
+ db.emit();
panic!();
}
}
self.bump_err_count();
}
pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
- self.emit.borrow_mut().emit(&sp.into(), msg, None, Note);
+ self.emit(&sp.into(), msg, Note);
}
pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
self.span_bug(sp, &format!("unimplemented {}", msg));
if self.treat_err_as_bug {
self.bug(msg);
}
- self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Fatal);
+ let mut db = DiagnosticBuilder::new(self,
+ Fatal,
+ msg);
+ db.emit();
self.bump_err_count();
FatalError
}
if self.treat_err_as_bug {
self.bug(msg);
}
- self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Error);
+ let mut db = DiagnosticBuilder::new(self,
+ Error,
+ msg);
+ db.emit();
self.bump_err_count();
}
pub fn warn(&self, msg: &str) {
- self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Warning);
+ let mut db = DiagnosticBuilder::new(self,
+ Warning,
+ msg);
+ db.emit();
}
pub fn note_without_error(&self, msg: &str) {
- self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Note);
+ let mut db = DiagnosticBuilder::new(self,
+ Note,
+ msg);
+ db.emit();
}
pub fn bug(&self, msg: &str) -> ! {
- self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Bug);
+ let mut db = DiagnosticBuilder::new(self,
+ Bug,
+ msg);
+ db.emit();
panic!(ExplicitBug);
}
pub fn unimpl(&self, msg: &str) -> ! {
msg: &str,
lvl: Level) {
if lvl == Warning && !self.can_emit_warnings { return }
- self.emit.borrow_mut().emit(&msp, msg, None, lvl);
+ let mut db = DiagnosticBuilder::new(self, lvl, msg);
+ db.set_span(msp.clone());
+ db.emit();
if !self.continue_after_error.get() { self.abort_if_errors(); }
}
pub fn emit_with_code(&self,
code: &str,
lvl: Level) {
if lvl == Warning && !self.can_emit_warnings { return }
- self.emit.borrow_mut().emit(&msp, msg, Some(code), lvl);
+ let mut db = DiagnosticBuilder::new_with_code(self,
+ lvl,
+ Some(code.to_owned()),
+ msg);
+ db.set_span(msp.clone());
+ db.emit();
if !self.continue_after_error.get() { self.abort_if_errors(); }
}
}
use codemap::CodeMap;
use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan};
use errors::registry::Registry;
-use errors::{Level, DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper};
+use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper};
use errors::emitter::Emitter;
use std::rc::Rc;
}
impl Emitter for JsonEmitter {
- fn emit(&mut self, span: &MultiSpan, msg: &str, code: Option<&str>, level: Level) {
- let data = Diagnostic::new(span, msg, code, level, self);
- if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
- panic!("failed to print diagnostics: {:?}", e);
- }
- }
-
fn emit_struct(&mut self, db: &DiagnosticBuilder) {
let data = Diagnostic::from_diagnostic_builder(db, self);
if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
}
impl<'a> Diagnostic<'a> {
- fn new(msp: &MultiSpan,
- msg: &'a str,
- code: Option<&str>,
- level: Level,
- je: &JsonEmitter)
- -> Diagnostic<'a> {
- Diagnostic {
- message: msg,
- code: DiagnosticCode::map_opt_string(code.map(|c| c.to_owned()), je),
- level: level.to_str(),
- spans: DiagnosticSpan::from_multispan(msp, je),
- children: vec![],
- rendered: None,
- }
- }
-
fn from_diagnostic_builder<'c>(db: &'c DiagnosticBuilder,
je: &JsonEmitter)
-> Diagnostic<'c> {