use std::rc::Rc;
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder, DiagnosticId};
use hir::def_id::{CrateNum, LOCAL_CRATE};
use hir::intravisit::{self, FnKind};
use hir;
}
}
- err.code(name);
+ err.code(DiagnosticId::Lint(name));
// Check for future incompatibility lints and issue a stronger warning.
let lints = sess.lint_store.borrow();
use util::common::{duration_to_secs_str, ErrorReported};
use syntax::ast::NodeId;
-use errors::{self, DiagnosticBuilder};
+use errors::{self, DiagnosticBuilder, DiagnosticId};
use errors::emitter::{Emitter, EmitterWriter};
use syntax::json::JsonEmitter;
use syntax::feature_gate;
pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
self.diagnostic().struct_span_warn_with_code(sp, msg, code)
}
pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
self.diagnostic().struct_span_err_with_code(sp, msg, code)
}
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
self.diagnostic().struct_err(msg)
}
- pub fn struct_err_with_code<'a>(&'a self, msg: &str, code: &str) -> DiagnosticBuilder<'a> {
+ pub fn struct_err_with_code<'a>(
+ &'a self,
+ msg: &str,
+ code: DiagnosticId,
+ ) -> DiagnosticBuilder<'a> {
self.diagnostic().struct_err_with_code(msg, code)
}
pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
}
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
panic!(self.diagnostic().span_fatal(sp, msg))
}
- pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) -> ! {
+ pub fn span_fatal_with_code<S: Into<MultiSpan>>(
+ &self,
+ sp: S,
+ msg: &str,
+ code: DiagnosticId,
+ ) -> ! {
panic!(self.diagnostic().span_fatal_with_code(sp, msg, code))
}
pub fn fatal(&self, msg: &str) -> ! {
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.diagnostic().span_err(sp, msg)
}
- pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
+ pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
self.diagnostic().span_err_with_code(sp, &msg, code)
}
pub fn err(&self, msg: &str) {
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.diagnostic().span_warn(sp, msg)
}
- pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
+ pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
self.diagnostic().span_warn_with_code(sp, msg, code)
}
pub fn warn(&self, msg: &str) {
use std::hash::{Hash, Hasher};
use syntax::ast;
use syntax_pos::{MultiSpan, Span};
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder, DiagnosticId};
use rustc::hir;
use rustc::hir::intravisit::{self, Visitor};
fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a>
{
self.tcx.sess.struct_span_err_with_code(sp, msg, code)
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self,
s: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
self.tcx.sess.struct_span_err_with_code(s, msg, code)
}
- pub fn span_err_with_code<S: Into<MultiSpan>>(&self, s: S, msg: &str, code: &str) {
+ pub fn span_err_with_code<S: Into<MultiSpan>>(
+ &self,
+ s: S,
+ msg: &str,
+ code: DiagnosticId,
+ ) {
self.tcx.sess.span_err_with_code(s, msg, code);
}
pub struct Diagnostic {
pub level: Level,
pub message: Vec<(String, Style)>,
- pub code: Option<String>,
+ pub code: Option<DiagnosticId>,
pub span: MultiSpan,
pub children: Vec<SubDiagnostic>,
pub suggestions: Vec<CodeSuggestion>,
}
+#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+pub enum DiagnosticId {
+ Error(String),
+ Lint(String),
+}
+
/// For example a note attached to an error.
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub struct SubDiagnostic {
Diagnostic::new_with_code(level, None, message)
}
- pub fn new_with_code(level: Level, code: Option<String>, message: &str) -> Self {
+ pub fn new_with_code(level: Level, code: Option<DiagnosticId>, message: &str) -> Self {
Diagnostic {
level,
message: vec![(message.to_owned(), Style::NoStyle)],
self
}
- pub fn code(&mut self, s: String) -> &mut Self {
+ pub fn code(&mut self, s: DiagnosticId) -> &mut Self {
self.code = Some(s);
self
}
// except according to those terms.
use Diagnostic;
+use DiagnosticId;
use DiagnosticStyledString;
use Level;
suggestions: Vec<String>)
-> &mut Self);
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
- forward!(pub fn code(&mut self, s: String) -> &mut Self);
+ forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
/// Convenience function for internal use, clients should use one of the
/// struct_* methods on Handler.
/// struct_* methods on Handler.
pub fn new_with_code(handler: &'a Handler,
level: Level,
- code: Option<String>,
+ code: Option<DiagnosticId>,
message: &str)
-> DiagnosticBuilder<'a> {
let diagnostic = Diagnostic::new_with_code(level, code, message);
use syntax_pos::{DUMMY_SP, FileMap, Span, MultiSpan, CharPos};
-use {Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, CodeMapper};
+use {Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, CodeMapper, DiagnosticId};
use RenderSpan::*;
use snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
use styled_buffer::StyledBuffer;
fn emit_message_default(&mut self,
msp: &MultiSpan,
msg: &Vec<(String, Style)>,
- code: &Option<String>,
+ code: &Option<DiagnosticId>,
level: &Level,
max_line_num_len: usize,
is_secondary: bool)
self.msg_to_buffer(&mut buffer, msg, max_line_num_len, "note", None);
} else {
buffer.append(0, &level.to_string(), Style::Level(level.clone()));
- match code {
- // only render error codes, not lint codes
- &Some(ref code) if code.starts_with("E") && code.len() == 5 => {
- buffer.append(0, "[", Style::Level(level.clone()));
- buffer.append(0, &code, Style::Level(level.clone()));
- buffer.append(0, "]", Style::Level(level.clone()));
- }
- _ => {}
+ // only render error codes, not lint codes
+ if let Some(DiagnosticId::Error(ref code)) = *code {
+ buffer.append(0, "[", Style::Level(level.clone()));
+ buffer.append(0, &code, Style::Level(level.clone()));
+ buffer.append(0, "]", Style::Level(level.clone()));
}
buffer.append(0, ": ", Style::HeaderMsg);
for &(ref text, _) in msg.iter() {
fn emit_messages_default(&mut self,
level: &Level,
message: &Vec<(String, Style)>,
- code: &Option<String>,
+ code: &Option<DiagnosticId>,
span: &MultiSpan,
children: &Vec<SubDiagnostic>) {
let max_line_num = self.get_max_line_num(span, children);
}
}
-pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString};
+pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString, DiagnosticId};
pub use diagnostic_builder::DiagnosticBuilder;
/// A handler deals with errors; certain errors
pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
result.set_span(sp);
- result.code(code.to_owned());
+ result.code(code);
if !self.can_emit_warnings {
result.cancel();
}
pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
result.set_span(sp);
- result.code(code.to_owned());
+ result.code(code);
result
}
// FIXME: This method should be removed (every error should have an associated error code).
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
DiagnosticBuilder::new(self, Level::Error, msg)
}
- pub fn struct_err_with_code<'a>(&'a self, msg: &str, code: &str) -> DiagnosticBuilder<'a> {
+ pub fn struct_err_with_code<'a>(
+ &'a self,
+ msg: &str,
+ code: DiagnosticId,
+ ) -> DiagnosticBuilder<'a> {
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
- result.code(code.to_owned());
+ result.code(code);
result
}
pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a> {
let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
result.set_span(sp);
- result.code(code.to_owned());
+ result.code(code);
result
}
pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> FatalError {
self.emit_with_code(&sp.into(), msg, code, Fatal);
FatalError
result.set_span(sp);
result
}
- pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
+ pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
self.emit_with_code(&sp.into(), msg, code, Error);
}
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.emit(&sp.into(), msg, Warning);
}
- pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
+ pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
self.emit_with_code(&sp.into(), msg, code, Warning);
}
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
self.abort_if_errors();
}
}
- pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: &str, lvl: Level) {
+ pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: DiagnosticId, lvl: Level) {
if lvl == Warning && !self.can_emit_warnings {
return;
}
- let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code.to_owned()), msg);
+ let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code), msg);
db.set_span(msp.clone());
db.emit();
if !self.continue_after_error.get() {
// except according to those terms.
use rustc::ty::{self, TyCtxt};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use syntax_pos::{MultiSpan, Span};
use std::fmt;
fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a>;
fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
msg: &str,
- code: &str)
+ code: DiagnosticId)
-> DiagnosticBuilder<'a>
{
self.sess.struct_span_err_with_code(sp, msg, code)
use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder, DiagnosticId};
use std::cell::{Cell, RefCell};
use std::cmp;
let target_sp = binding_error.target.iter().map(|x| *x).collect::<Vec<_>>();
let msp = MultiSpan::from_spans(target_sp.clone());
let msg = format!("variable `{}` is not bound in all patterns", binding_error.name);
- let mut err = resolver.session.struct_span_err_with_code(msp, &msg, "E0408");
+ let mut err = resolver.session.struct_span_err_with_code(
+ msp,
+ &msg,
+ DiagnosticId::Error("E0408".into()),
+ );
for sp in target_sp {
err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name));
}
(format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
format!("not found in {}", mod_str), item_span)
};
+ let code = DiagnosticId::Error(code.into());
let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
// Emit special messages for unresolved `Self` and `self`.
if is_self_type(path, ns) {
__diagnostic_used!(E0411);
- err.code("E0411".into());
+ err.code(DiagnosticId::Error("E0411".into()));
err.span_label(span, "`Self` is only available in traits and impls");
return (err, Vec::new());
}
if is_self_value(path, ns) {
__diagnostic_used!(E0424);
- err.code("E0424".into());
+ err.code(DiagnosticId::Error("E0424".into()));
err.span_label(span, format!("`self` value is only available in \
methods with `self` parameter"));
return (err, Vec::new());
use rustc::ty::TyCtxt;
use rustc::util::common::{time, time_depth, set_time_depth, path2cstr, print_time_passes_entry};
use rustc::util::fs::{link_or_copy, rename_or_copy_remove};
-use errors::{self, Handler, Level, DiagnosticBuilder, FatalError};
+use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
use errors::emitter::{Emitter};
use syntax::attr;
use syntax::ext::hygiene::Mark;
struct Diagnostic {
msg: String,
- code: Option<String>,
+ code: Option<DiagnosticId>,
lvl: Level,
}
Some(ref code) => {
handler.emit_with_code(&MultiSpan::new(),
&diag.msg,
- &code,
+ code.clone(),
diag.lvl);
}
None => {
use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
use rustc::ty::maps::Providers;
use rustc::ty::util::{Representability, IntTypeExt};
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder, DiagnosticId};
use require_c_abi_if_variadic;
use session::{CompileIncomplete, Session};
use TypeAndSubsts;
if expected_count == 1 {""} else {"s"},
arg_count,
if arg_count == 1 {" was"} else {"s were"}),
- error_code);
+ DiagnosticId::Error(error_code.to_owned()));
if let Some(def_s) = def_span {
err.span_label(def_s, "defined here");
macro_rules! span_fatal {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.span_fatal_with_code($span, &format!($($message)*), stringify!($code))
+ $session.span_fatal_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
macro_rules! span_err {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.span_err_with_code($span, &format!($($message)*), stringify!($code))
+ $session.span_err_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
macro_rules! span_warn {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.span_warn_with_code($span, &format!($($message)*), stringify!($code))
+ $session.span_warn_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
macro_rules! struct_err {
($session:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.struct_err_with_code(&format!($($message)*), stringify!($code))
+ $session.struct_err_with_code(
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
if $is_warning {
- $session.span_warn_with_code($span, &format!($($message)*), stringify!($code))
+ $session.span_warn_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
} else {
- $session.span_err_with_code($span, &format!($($message)*), stringify!($code))
+ $session.span_err_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
}
})
}
macro_rules! struct_span_fatal {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.struct_span_fatal_with_code($span, &format!($($message)*), stringify!($code))
+ $session.struct_span_fatal_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
macro_rules! struct_span_err {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code))
+ $session.struct_span_err_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
macro_rules! struct_span_warn {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
- $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code))
+ $session.struct_span_warn_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
})
}
($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
if $is_warning {
- $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code))
+ $session.struct_span_warn_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
} else {
- $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code))
+ $session.struct_span_err_with_code(
+ $span,
+ &format!($($message)*),
+ $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
+ )
}
})
}
use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan};
use errors::registry::Registry;
use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper};
+use errors::DiagnosticId;
use errors::emitter::Emitter;
use std::rc::Rc;
}
impl DiagnosticCode {
- fn map_opt_string(s: Option<String>, je: &JsonEmitter) -> Option<DiagnosticCode> {
+ fn map_opt_string(s: Option<DiagnosticId>, je: &JsonEmitter) -> Option<DiagnosticCode> {
s.map(|s| {
-
+ let s = match s {
+ DiagnosticId::Error(s) => s,
+ DiagnosticId::Lint(s) => s,
+ };
let explanation = je.registry
.as_ref()
.and_then(|registry| registry.find_description(&s));