about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver 'ker' Schneider <rust19446194516@oli-obk.de>2015-12-27 02:17:16 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2016-03-10 12:50:12 +0100
commit0d13231a4cfb1f24c7cfc8168d15d19c63bdbdba (patch)
tree815fde30b071c43f826e004b3f3865a257758cc1
parent7bde56e14941924c17daeaa1996d61d0ffdb6bd1 (diff)
downloadrust-0d13231a4cfb1f24c7cfc8168d15d19c63bdbdba.tar.gz
rust-0d13231a4cfb1f24c7cfc8168d15d19c63bdbdba.zip
const eval failures aren't fatal, simply return a dummy instead
-rw-r--r--src/librustc/middle/const_eval.rs16
-rw-r--r--src/librustc/middle/ty/mod.rs2
-rw-r--r--src/librustc_trans/trans/mir/constant.rs1
3 files changed, 16 insertions, 3 deletions
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index c3f8d7bf959..bc8dfd6c7b0 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -267,6 +267,10 @@ pub enum ConstVal {
     Array(ast::NodeId, u64),
     Repeat(ast::NodeId, u64),
     Char(char),
+    /// A value that only occurs in case `eval_const_expr` reported an error. You should never
+    /// handle this case. Its sole purpose is to allow more errors to be reported instead of
+    /// causing a fatal error.
+    Dummy,
 }
 
 impl hash::Hash for ConstVal {
@@ -283,6 +287,7 @@ impl hash::Hash for ConstVal {
             Array(a, n) => { a.hash(state); n.hash(state) },
             Repeat(a, n) => { a.hash(state); n.hash(state) },
             Char(c) => c.hash(state),
+            Dummy => ().hash(state),
         }
     }
 }
@@ -305,6 +310,7 @@ impl PartialEq for ConstVal {
             (&Array(a, an), &Array(b, bn)) => (a == b) && (an == bn),
             (&Repeat(a, an), &Repeat(b, bn)) => (a == b) && (an == bn),
             (&Char(a), &Char(b)) => a == b,
+            (&Dummy, &Dummy) => true, // FIXME: should this be false?
             _ => false,
         }
     }
@@ -326,6 +332,7 @@ impl ConstVal {
             Array(..) => "array",
             Repeat(..) => "repeat",
             Char(..) => "char",
+            Dummy => "dummy value",
         }
     }
 }
@@ -393,7 +400,12 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
 pub fn eval_const_expr(tcx: &TyCtxt, e: &Expr) -> ConstVal {
     match eval_const_expr_partial(tcx, e, ExprTypeChecked, None) {
         Ok(r) => r,
-        Err(s) => tcx.sess.span_fatal(s.span, &s.description())
+        // non-const path still needs to be a fatal error, because enums are funky
+        Err(ref s) if s.kind == NonConstPath => tcx.sess.span_fatal(s.span, &s.description()),
+        Err(s) => {
+            tcx.sess.span_err(s.span, &s.description());
+            Dummy
+        },
     }
 }
 
@@ -405,7 +417,7 @@ pub struct ConstEvalErr {
     pub kind: ErrKind,
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub enum ErrKind {
     CannotCast,
     CannotCastTo(&'static str),
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index c98ae2cceab..f8ab98a15d9 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -1546,7 +1546,7 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     /// Asserts this is a struct and returns the struct's unique
     /// variant.
     pub fn struct_variant(&self) -> &VariantDefData<'tcx, 'container> {
-        assert!(self.adt_kind() == AdtKind::Struct);
+        assert_eq!(self.adt_kind(), AdtKind::Struct);
         &self.variants[0]
     }
 
diff --git a/src/librustc_trans/trans/mir/constant.rs b/src/librustc_trans/trans/mir/constant.rs
index 2c251a4cd57..c20d8b01eb7 100644
--- a/src/librustc_trans/trans/mir/constant.rs
+++ b/src/librustc_trans/trans/mir/constant.rs
@@ -93,6 +93,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 })
             },
             ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
+            ConstVal::Dummy => unreachable!(),
             ConstVal::Function(_) => C_nil(ccx)
         }
     }