]> git.lizzy.rs Git - rust.git/commitdiff
librustc: add {span_,}bug! macros
authorBenjamin Herr <ben@0x539.de>
Wed, 23 Mar 2016 23:35:26 +0000 (00:35 +0100)
committerBenjamin Herr <ben@0x539.de>
Thu, 31 Mar 2016 20:04:23 +0000 (22:04 +0200)
... as single "internal compiler error" entry point.

The macros pass `file!()`, `line!()` and `format_args!(...)` on to a
cold, never-inlined function, ultimately calling `bug()` or `span_bug()`
on the `Handler` from `session::diagnostic()` via the tcx in tls or,
failing that, panicking directly.

src/librustc/macros.rs
src/librustc/session/mod.rs

index ed764ebd9f95dd4e27b579342fc0f4c66e77a486..76dca1bb5b64941b61d989de99b18515c84c47dd 100644 (file)
@@ -44,3 +44,18 @@ pub fn from_u32(u: u32) -> Option<$name> {
         }
     }
 }
+
+#[macro_export]
+macro_rules! bug {
+    () => ( bug!("impossible case reached") );
+    ($($message:tt)*) => ({
+        $crate::session::bug_fmt(file!(), line!(), format_args!($($message)*))
+    })
+}
+
+#[macro_export]
+macro_rules! span_bug {
+    ($span:expr, $($message:tt)*) => ({
+        $crate::session::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*))
+    })
+}
index 20ca62132542f71893a14ad5f6afb46073be1bda..d8792928f5e03fa53c0d69561437787040b6b706 100644 (file)
@@ -12,6 +12,7 @@
 use middle::cstore::CrateStore;
 use middle::dependency_format;
 use session::search_paths::PathKind;
+use ty::tls;
 use util::nodemap::{NodeMap, FnvHashMap};
 use mir::transform as mir_pass;
 
@@ -35,6 +36,7 @@
 use std::collections::{HashMap, HashSet};
 use std::env;
 use std::rc::Rc;
+use std::fmt;
 
 pub mod config;
 pub mod filesearch;
@@ -541,3 +543,35 @@ pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
         Err(err_count)
     }
 }
+
+#[cold]
+#[inline(never)]
+pub fn bug_fmt(file: &'static str, line: u32, args: fmt::Arguments) -> ! {
+    // this wrapper mostly exists so I don't have to write a fully
+    // qualified path of None::<Span> inside the bug!() macro defintion
+    opt_span_bug_fmt(file, line, None::<Span>, args);
+}
+
+#[cold]
+#[inline(never)]
+pub fn span_bug_fmt<S: Into<MultiSpan>>(file: &'static str,
+                                        line: u32,
+                                        span: S,
+                                        args: fmt::Arguments) -> ! {
+    opt_span_bug_fmt(file, line, Some(span), args);
+}
+
+fn opt_span_bug_fmt<S: Into<MultiSpan>>(file: &'static str,
+                                          line: u32,
+                                          span: Option<S>,
+                                          args: fmt::Arguments) -> ! {
+    tls::with_opt(move |tcx| {
+        let msg = format!("{}:{}: {}", file, line, args);
+        match (tcx, span) {
+            (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg),
+            (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg),
+            (None, _) => panic!(msg)
+        }
+    });
+    unreachable!();
+}