about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-14 05:26:29 -0700
committerbors <bors@rust-lang.org>2014-03-14 05:26:29 -0700
commita1c7ebee1ac65151835f8b82d7140d52402c22c2 (patch)
tree248008ed59eb85597d31d5e420994ab602bc1745
parentd367482491ab82af8cc88f2f822fef725237cfbe (diff)
parentedb6b025c48205c5084a648c7ef7859adbf5c705 (diff)
downloadrust-a1c7ebee1ac65151835f8b82d7140d52402c22c2.tar.gz
rust-a1c7ebee1ac65151835f8b82d7140d52402c22c2.zip
auto merge of #12874 : huonw/rust/printier-rustc, r=alexcrichton
rustc: make stack traces print for .span_bug/.bug.

Previously a call to either of those to diagnostic printers would defer
to the `fatal` equivalents, which explicitly silence the stderr
printing, including a stack trace from `RUST_LOG=std::rt::backtrace`.

This splits the bug printers out to their own diagnostic type so that
things work properly.

Also, this removes the `Ok(...)` that was being printed around the
subtask's stderr output.
-rw-r--r--src/librustc/lib.rs28
-rw-r--r--src/libsyntax/diagnostic.rs21
2 files changed, 32 insertions, 17 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index b8c1bdd1b4d..9fe4a122b4a 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -134,6 +134,9 @@ pub mod lib {
     pub mod llvmdeps;
 }
 
+static BUG_REPORT_URL: &'static str =
+    "http://static.rust-lang.org/doc/master/complement-bugreport.html";
+
 pub fn version(argv0: &str) {
     let vers = match option_env!("CFG_VERSION") {
         Some(vers) => vers,
@@ -393,20 +396,31 @@ pub fn monitor(f: proc()) {
             // Task failed without emitting a fatal diagnostic
             if !value.is::<diagnostic::FatalError>() {
                 let mut emitter = diagnostic::EmitterWriter::stderr();
-                emitter.emit(
-                    None,
-                    diagnostic::ice_msg("unexpected failure"),
-                    diagnostic::Error);
+
+                // a .span_bug or .bug call has already printed what
+                // it wants to print.
+                if !value.is::<diagnostic::ExplicitBug>() {
+                    emitter.emit(
+                        None,
+                        "unexpected failure",
+                        diagnostic::Bug);
+                }
 
                 let xs = [
-                    ~"the compiler hit an unexpected failure path. \
-                     this is a bug",
+                    ~"the compiler hit an unexpected failure path. this is a bug.",
+                    "we would appreciate a bug report: " + BUG_REPORT_URL,
+                    ~"run with `RUST_LOG=std::rt::backtrace` for a backtrace",
                 ];
                 for note in xs.iter() {
                     emitter.emit(None, *note, diagnostic::Note)
                 }
 
-                println!("{}", r.read_to_str());
+                match r.read_to_str() {
+                    Ok(s) => println!("{}", s),
+                    Err(e) => emitter.emit(None,
+                                           format!("failed to read internal stderr: {}", e),
+                                           diagnostic::Error),
+                }
             }
 
             // Fail so the process returns a failure code, but don't pollute the
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 0cf13cfaba5..2da8b786805 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -17,8 +17,6 @@ use std::io;
 use std::iter::range;
 use term;
 
-static BUG_REPORT_URL: &'static str =
-    "http://static.rust-lang.org/doc/master/complement-bugreport.html";
 // maximum number of lines we will print for each error; arbitrary.
 static MAX_LINES: uint = 6u;
 
@@ -34,6 +32,10 @@ pub trait Emitter {
 /// how a rustc task died (if so desired).
 pub struct FatalError;
 
+/// Signifies that the compiler died with an explicit call to `.bug`
+/// or `.span_bug` rather than a failed assertion, etc.
+pub struct ExplicitBug;
+
 // a span-handler is like a handler but also
 // accepts span information for source-location
 // reporting.
@@ -61,7 +63,8 @@ impl SpanHandler {
         self.handler.custom_emit(&*self.cm, sp, msg, Note);
     }
     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
-        self.span_fatal(sp, ice_msg(msg));
+        self.handler.emit(Some((&*self.cm, sp)), msg, Bug);
+        fail!(ExplicitBug);
     }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
         self.span_bug(sp, ~"unimplemented " + msg);
@@ -116,7 +119,8 @@ impl Handler {
         self.emit.borrow_mut().get().emit(None, msg, Note);
     }
     pub fn bug(&self, msg: &str) -> ! {
-        self.fatal(ice_msg(msg));
+        self.emit.borrow_mut().get().emit(None, msg, Bug);
+        fail!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
         self.bug(~"unimplemented " + msg);
@@ -133,11 +137,6 @@ impl Handler {
     }
 }
 
-pub fn ice_msg(msg: &str) -> ~str {
-    format!("internal compiler error: {}\nThis message reflects a bug in the Rust compiler. \
-            \nWe would appreciate a bug report: {}", msg, BUG_REPORT_URL)
-}
-
 pub fn mk_span_handler(handler: @Handler, cm: @codemap::CodeMap)
                        -> @SpanHandler {
     @SpanHandler {
@@ -159,6 +158,7 @@ pub fn mk_handler(e: ~Emitter) -> @Handler {
 
 #[deriving(Eq)]
 pub enum Level {
+    Bug,
     Fatal,
     Error,
     Warning,
@@ -170,6 +170,7 @@ impl fmt::Show for Level {
         use std::fmt::Show;
 
         match *self {
+            Bug => "error: internal compiler error".fmt(f),
             Fatal | Error => "error".fmt(f),
             Warning => "warning".fmt(f),
             Note => "note".fmt(f),
@@ -180,7 +181,7 @@ impl fmt::Show for Level {
 impl Level {
     fn color(self) -> term::color::Color {
         match self {
-            Fatal | Error => term::color::BRIGHT_RED,
+            Bug | Fatal | Error => term::color::BRIGHT_RED,
             Warning => term::color::BRIGHT_YELLOW,
             Note => term::color::BRIGHT_GREEN
         }