about summary refs log tree commit diff
path: root/src/libsyntax/errors
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/errors')
-rw-r--r--src/libsyntax/errors/emitter.rs163
-rw-r--r--src/libsyntax/errors/json.rs2
-rw-r--r--src/libsyntax/errors/mod.rs7
3 files changed, 74 insertions, 98 deletions
diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs
index f851937d82b..2b29de7fd71 100644
--- a/src/libsyntax/errors/emitter.rs
+++ b/src/libsyntax/errors/emitter.rs
@@ -24,6 +24,8 @@ use std::io;
 use std::rc::Rc;
 use term;
 
+/// 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);
@@ -32,27 +34,44 @@ pub trait Emitter {
     fn emit_struct(&mut self, db: &DiagnosticBuilder);
 }
 
-/// A core trait that can only handle very simple messages: those
-/// without spans or any real structure. Used only in specific contexts.
-pub trait RudimentaryEmitter {
-    fn emit_rudimentary(&mut self, msg: &str, code: Option<&str>, lvl: Level);
+pub trait CoreEmitter {
+    fn emit_message(&mut self,
+                    rsp: &RenderSpan,
+                    msg: &str,
+                    code: Option<&str>,
+                    lvl: Level,
+                    is_header: bool);
 }
 
-impl<T: RudimentaryEmitter> Emitter for T {
+impl<T: CoreEmitter> Emitter for T {
     fn emit(&mut self,
             msp: &MultiSpan,
             msg: &str,
             code: Option<&str>,
             lvl: Level) {
-        assert!(msp.primary_span().is_none(), "Rudimenatry emitters can't handle spans");
-        self.emit_rudimentary(msg, code, lvl);
+        self.emit_message(&FullSpan(msp.clone()),
+                          msg,
+                          code,
+                          lvl,
+                          true);
     }
 
     fn emit_struct(&mut self, db: &DiagnosticBuilder) {
-        self.emit(&db.span, &db.message, db.code.as_ref().map(|s| &**s), db.level);
+        self.emit_message(&FullSpan(db.span.clone()),
+                          &db.message,
+                          db.code.as_ref().map(|s| &**s),
+                          db.level,
+                          true);
         for child in &db.children {
-            assert!(child.render_span.is_none(), "Rudimentary emitters can't handle render spans");
-            self.emit(&child.span, &child.message, None, child.level);
+            let render_span = child.render_span
+                                   .clone()
+                                   .unwrap_or_else(
+                                       || FullSpan(child.span.clone()));
+            self.emit_message(&render_span,
+                              &child.message,
+                              None,
+                              child.level,
+                              false);
         }
     }
 }
@@ -83,11 +102,14 @@ pub struct BasicEmitter {
     dst: Destination,
 }
 
-impl RudimentaryEmitter for BasicEmitter {
-    fn emit_rudimentary(&mut self,
-                        msg: &str,
-                        code: Option<&str>,
-                        lvl: Level) {
+impl CoreEmitter for BasicEmitter {
+    fn emit_message(&mut self,
+                    _rsp: &RenderSpan,
+                    msg: &str,
+                    code: Option<&str>,
+                    lvl: Level,
+                    _is_header: bool) {
+        // we ignore the span as we have no access to a codemap at this point
         if let Err(e) = print_diagnostic(&mut self.dst, "", lvl, msg, code) {
             panic!("failed to print diagnostics: {:?}", e);
         }
@@ -112,28 +134,16 @@ pub struct EmitterWriter {
     first: bool,
 }
 
-impl Emitter for EmitterWriter {
-    fn emit(&mut self,
-            msp: &MultiSpan,
-            msg: &str,
-            code: Option<&str>,
-            lvl: Level) {
-        self.emit_multispan(msp, msg, code, lvl, true);
-    }
-
-    fn emit_struct(&mut self, db: &DiagnosticBuilder) {
-        self.emit_multispan(&db.span, &db.message,
-            db.code.as_ref().map(|s| &**s), db.level, true);
-
-        for child in &db.children {
-            match child.render_span {
-                Some(ref sp) =>
-                    self.emit_renderspan(sp, &child.message,
-                        child.level),
-                None =>
-                    self.emit_multispan(&child.span,
-                        &child.message, None, child.level, false),
-            }
+impl CoreEmitter for EmitterWriter {
+    fn emit_message(&mut self,
+                    rsp: &RenderSpan,
+                    msg: &str,
+                    code: Option<&str>,
+                    lvl: Level,
+                    is_header: bool) {
+        match self.emit_message_(rsp, msg, code, lvl, is_header) {
+            Ok(()) => { }
+            Err(e) => panic!("failed to emit error: {}", e)
         }
     }
 }
@@ -173,83 +183,56 @@ impl EmitterWriter {
         EmitterWriter { dst: Raw(dst), registry: registry, cm: code_map, first: true }
     }
 
-    fn emit_multispan(&mut self,
-                      span: &MultiSpan,
-                      msg: &str,
-                      code: Option<&str>,
-                      lvl: Level,
-                      is_header: bool) {
+    fn emit_message_(&mut self,
+                     rsp: &RenderSpan,
+                     msg: &str,
+                     code: Option<&str>,
+                     lvl: Level,
+                     is_header: bool)
+                     -> io::Result<()> {
         if is_header {
             if self.first {
                 self.first = false;
             } else {
-                match write!(self.dst, "\n") {
-                    Ok(_) => { }
-                    Err(e) => {
-                        panic!("failed to print diagnostics: {:?}", e)
-                    }
-                }
+                write!(self.dst, "\n")?;
             }
         }
 
-        let error = match span.primary_span() {
-            Some(COMMAND_LINE_SP) => {
-                self.emit_(&FileLine(span.clone()), msg, code, lvl)
-            }
-            Some(DUMMY_SP) | None => {
-                print_diagnostic(&mut self.dst, "", lvl, msg, code)
-            }
-            Some(_) => {
-                self.emit_(&FullSpan(span.clone()), msg, code, lvl)
-            }
-        };
-
-        if let Err(e) = error {
-            panic!("failed to print diagnostics: {:?}", e);
-        }
-    }
-
-    fn emit_renderspan(&mut self, sp: &RenderSpan, msg: &str, lvl: Level) {
-        if let Err(e) = self.emit_(sp, msg, None, lvl) {
-            panic!("failed to print diagnostics: {:?}", e);
-        }
-    }
-
-    fn emit_(&mut self,
-             rsp: &RenderSpan,
-             msg: &str,
-             code: Option<&str>,
-             lvl: Level)
-             -> io::Result<()> {
-        let msp = rsp.span();
-        let primary_span = msp.primary_span();
-
         match code {
             Some(code) if self.registry.as_ref()
-                          .and_then(|registry| registry.find_description(code)).is_some() =>
-            {
+                                       .and_then(|registry| registry.find_description(code))
+                                       .is_some() => {
                 let code_with_explain = String::from("--explain ") + code;
                 print_diagnostic(&mut self.dst, "", lvl, msg, Some(&code_with_explain))?
             }
-            _ => print_diagnostic(&mut self.dst, "", lvl, msg, code)?
+            _ => {
+                print_diagnostic(&mut self.dst, "", lvl, msg, code)?
+            }
         }
 
+        // Watch out for various nasty special spans; don't try to
+        // print any filename or anything for those.
+        match rsp.span().primary_span() {
+            Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => {
+                return Ok(());
+            }
+            _ => { }
+        }
+
+        // Otherwise, print out the snippet etc as needed.
         match *rsp {
-            FullSpan(_) => {
+            FullSpan(ref msp) => {
                 self.highlight_lines(msp, lvl)?;
-                if let Some(primary_span) = primary_span {
+                if let Some(primary_span) = msp.primary_span() {
                     self.print_macro_backtrace(primary_span)?;
                 }
             }
             Suggestion(ref suggestion) => {
                 self.highlight_suggestion(suggestion)?;
-                if let Some(primary_span) = primary_span {
+                if let Some(primary_span) = rsp.span().primary_span() {
                     self.print_macro_backtrace(primary_span)?;
                 }
             }
-            FileLine(..) => {
-                // no source text in this case!
-            }
         }
 
         Ok(())
diff --git a/src/libsyntax/errors/json.rs b/src/libsyntax/errors/json.rs
index b343c3f3fbb..93c6268ccae 100644
--- a/src/libsyntax/errors/json.rs
+++ b/src/libsyntax/errors/json.rs
@@ -294,7 +294,6 @@ impl DiagnosticSpan {
 
     fn from_render_span(rsp: &RenderSpan, je: &JsonEmitter) -> Vec<DiagnosticSpan> {
         match *rsp {
-            RenderSpan::FileLine(ref msp) |
             RenderSpan::FullSpan(ref msp) =>
                 DiagnosticSpan::from_multispan(msp, je),
             RenderSpan::Suggestion(ref suggestion) =>
@@ -356,7 +355,6 @@ impl DiagnosticCode {
 impl JsonEmitter {
     fn render(&self, render_span: &RenderSpan) -> Option<String> {
         match *render_span {
-            RenderSpan::FileLine(_) |
             RenderSpan::FullSpan(_) => {
                 None
             }
diff --git a/src/libsyntax/errors/mod.rs b/src/libsyntax/errors/mod.rs
index 0de2e067802..d533ffb981a 100644
--- a/src/libsyntax/errors/mod.rs
+++ b/src/libsyntax/errors/mod.rs
@@ -38,10 +38,6 @@ pub enum RenderSpan {
     /// of hypothetical source code, where each `String` is spliced
     /// into the lines in place of the code covered by each span.
     Suggestion(CodeSuggestion),
-
-    /// A FileLine renders with just a line for the message prefixed
-    /// by file:linenum.
-    FileLine(MultiSpan),
 }
 
 #[derive(Clone)]
@@ -54,8 +50,7 @@ impl RenderSpan {
     fn span(&self) -> &MultiSpan {
         match *self {
             FullSpan(ref msp) |
-            Suggestion(CodeSuggestion { ref msp, .. }) |
-            FileLine(ref msp) =>
+            Suggestion(CodeSuggestion { ref msp, .. }) =>
                 msp
         }
     }