]> git.lizzy.rs Git - rust.git/commitdiff
rustc_const_eval: move ConstEvalErr to the rustc crate.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Thu, 13 Apr 2017 13:40:03 +0000 (16:40 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Sat, 15 Apr 2017 22:31:06 +0000 (01:31 +0300)
21 files changed:
src/Cargo.lock
src/librustc/diagnostics.rs
src/librustc/middle/const_val.rs
src/librustc/ty/maps.rs
src/librustc_const_eval/Cargo.toml
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/diagnostics.rs
src/librustc_const_eval/eval.rs
src/librustc_const_eval/lib.rs
src/librustc_const_eval/pattern.rs
src/librustc_metadata/decoder.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/mod.rs
src/librustc_passes/consts.rs
src/librustc_trans/Cargo.toml
src/librustc_trans/consts.rs
src/librustc_trans/lib.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/trans_item.rs
src/librustc_typeck/collect.rs

index 1fa256197ce528a537269316cc7e2c873b2b9ef0..c4b5366d4a324190ed9336e7444db75ecba4b878 100644 (file)
@@ -503,7 +503,6 @@ name = "rustc_const_eval"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "graphviz 0.0.0",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -731,7 +730,6 @@ dependencies = [
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_bitflags 0.0.0",
- "rustc_const_eval 0.0.0",
  "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
index 5a0fbf8efb70778cc07954fe2c60d8436b1d7e0b..8a391f9cde3a3a37b9dc74dddd09106617a86292 100644 (file)
@@ -327,6 +327,25 @@ struct ListNode {
 This works because `Box` is a pointer, so its size is well-known.
 "##,
 
+E0080: r##"
+This error indicates that the compiler was unable to sensibly evaluate an
+constant expression that had to be evaluated. Attempting to divide by 0
+or causing integer overflow are two ways to induce this error. For example:
+
+```compile_fail,E0080
+enum Enum {
+    X = (1 << 500),
+    Y = (1 / 0)
+}
+```
+
+Ensure that the expressions given can be evaluated as the desired integer type.
+See the FFI section of the Reference for more information about using a custom
+integer type:
+
+https://doc.rust-lang.org/reference.html#ffi-attributes
+"##,
+
 E0106: r##"
 This error indicates that a lifetime is missing from a type. If it is an error
 inside a function signature, the problem may be with failing to adhere to the
index d81f89827d93814de111839dc33661c97fc282cf..9315f7f58081af4d036d76de0ac0abdc337a6821 100644 (file)
@@ -8,17 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::symbol::InternedString;
-use syntax::ast;
-use std::rc::Rc;
+use self::ConstVal::*;
+pub use rustc_const_math::ConstInt;
+
 use hir::def_id::DefId;
+use ty::TyCtxt;
 use ty::subst::Substs;
 use rustc_const_math::*;
 
-use self::ConstVal::*;
-pub use rustc_const_math::ConstInt;
+use graphviz::IntoCow;
+use errors::DiagnosticBuilder;
+use syntax::symbol::InternedString;
+use syntax::ast;
+use syntax_pos::Span;
 
+use std::borrow::Cow;
 use std::collections::BTreeMap;
+use std::rc::Rc;
+
+pub type EvalResult<'tcx> = Result<ConstVal<'tcx>, ConstEvalErr<'tcx>>;
 
 #[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
 pub enum ConstVal<'tcx> {
@@ -61,3 +69,149 @@ pub fn to_const_int(&self) -> Option<ConstInt> {
         }
     }
 }
+
+#[derive(Clone, Debug)]
+pub struct ConstEvalErr<'tcx> {
+    pub span: Span,
+    pub kind: ErrKind<'tcx>,
+}
+
+#[derive(Clone, Debug)]
+pub enum ErrKind<'tcx> {
+    CannotCast,
+    MissingStructField,
+    NegateOn(ConstVal<'tcx>),
+    NotOn(ConstVal<'tcx>),
+    CallOn(ConstVal<'tcx>),
+
+    NonConstPath,
+    UnimplementedConstVal(&'static str),
+    ExpectedConstTuple,
+    ExpectedConstStruct,
+    IndexedNonVec,
+    IndexNotUsize,
+    IndexOutOfBounds { len: u64, index: u64 },
+
+    MiscBinaryOp,
+    MiscCatchAll,
+
+    IndexOpFeatureGated,
+    Math(ConstMathErr),
+
+    ErroneousReferencedConstant(Box<ConstEvalErr<'tcx>>),
+
+    TypeckError
+}
+
+impl<'tcx> From<ConstMathErr> for ErrKind<'tcx> {
+    fn from(err: ConstMathErr) -> ErrKind<'tcx> {
+        match err {
+            ConstMathErr::UnsignedNegation => ErrKind::TypeckError,
+            _ => ErrKind::Math(err)
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub enum ConstEvalErrDescription<'a> {
+    Simple(Cow<'a, str>),
+}
+
+impl<'a> ConstEvalErrDescription<'a> {
+    /// Return a one-line description of the error, for lints and such
+    pub fn into_oneline(self) -> Cow<'a, str> {
+        match self {
+            ConstEvalErrDescription::Simple(simple) => simple,
+        }
+    }
+}
+
+impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
+    pub fn description(&self) -> ConstEvalErrDescription {
+        use self::ErrKind::*;
+        use self::ConstEvalErrDescription::*;
+
+        macro_rules! simple {
+            ($msg:expr) => ({ Simple($msg.into_cow()) });
+            ($fmt:expr, $($arg:tt)+) => ({
+                Simple(format!($fmt, $($arg)+).into_cow())
+            })
+        }
+
+        match self.kind {
+            CannotCast => simple!("can't cast this type"),
+            NegateOn(ref const_val) => simple!("negate on {}", const_val.description()),
+            NotOn(ref const_val) => simple!("not on {}", const_val.description()),
+            CallOn(ref const_val) => simple!("call on {}", const_val.description()),
+
+            MissingStructField  => simple!("nonexistent struct field"),
+            NonConstPath        => simple!("non-constant path in constant expression"),
+            UnimplementedConstVal(what) =>
+                simple!("unimplemented constant expression: {}", what),
+            ExpectedConstTuple => simple!("expected constant tuple"),
+            ExpectedConstStruct => simple!("expected constant struct"),
+            IndexedNonVec => simple!("indexing is only supported for arrays"),
+            IndexNotUsize => simple!("indices must be of type `usize`"),
+            IndexOutOfBounds { len, index } => {
+                simple!("index out of bounds: the len is {} but the index is {}",
+                        len, index)
+            }
+
+            MiscBinaryOp => simple!("bad operands for binary"),
+            MiscCatchAll => simple!("unsupported constant expr"),
+            IndexOpFeatureGated => simple!("the index operation on const values is unstable"),
+            Math(ref err) => Simple(err.description().into_cow()),
+
+            ErroneousReferencedConstant(_) => simple!("could not evaluate referenced constant"),
+
+            TypeckError => simple!("type-checking failed"),
+        }
+    }
+
+    pub fn struct_error(&self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        primary_span: Span,
+        primary_kind: &str)
+        -> DiagnosticBuilder<'gcx>
+    {
+        let mut err = self;
+        while let &ConstEvalErr {
+            kind: ErrKind::ErroneousReferencedConstant(box ref i_err), ..
+        } = err {
+            err = i_err;
+        }
+
+        let mut diag = struct_span_err!(tcx.sess, err.span, E0080, "constant evaluation error");
+        err.note(tcx, primary_span, primary_kind, &mut diag);
+        diag
+    }
+
+    pub fn note(&self,
+        _tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        primary_span: Span,
+        primary_kind: &str,
+        diag: &mut DiagnosticBuilder)
+    {
+        match self.description() {
+            ConstEvalErrDescription::Simple(message) => {
+                diag.span_label(self.span, &message);
+            }
+        }
+
+        if !primary_span.contains(self.span) {
+            diag.span_note(primary_span,
+                        &format!("for {} here", primary_kind));
+        }
+    }
+
+    pub fn report(&self,
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        primary_span: Span,
+        primary_kind: &str)
+    {
+        if let ErrKind::TypeckError = self.kind {
+            return;
+        }
+        self.struct_error(tcx, primary_span, primary_kind).emit();
+    }
+}
index 868ccad8a3a90618078a7528c2c9488076ce8aaf..e9eb5e97582bf136975d6332cb6e1925a17ebd62 100644 (file)
@@ -10,7 +10,7 @@
 
 use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use middle::const_val::ConstVal;
+use middle::const_val;
 use middle::privacy::AccessLevels;
 use mir;
 use session::CompileResult;
@@ -443,7 +443,7 @@ fn default() -> Self {
 
     /// Results of evaluating monomorphic constants embedded in
     /// other items, such as enum variant explicit discriminants.
-    pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
+    pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> const_val::EvalResult<'tcx>,
 
     /// Performs the privacy check and computes "access levels".
     pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
index 907410f74dca4f268697e32d036a606894924996..bbc6148082494f905194f9be7aa9b200b075686f 100644 (file)
@@ -17,5 +17,4 @@ rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 syntax = { path = "../libsyntax" }
-graphviz = { path = "../libgraphviz" }
 syntax_pos = { path = "../libsyntax_pos" }
index 9d55281d019d9ee579a4d755e47b6303d674ec04..f1ab6a00aa2effb1e3528546dc825b9aec8b0319 100644 (file)
@@ -14,8 +14,6 @@
 
 use pattern::{Pattern, PatternContext, PatternError, PatternKind};
 
-use eval::report_const_eval_err;
-
 use rustc::dep_graph::DepNode;
 
 use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
@@ -108,27 +106,29 @@ fn visit_body(&mut self, body: &'tcx hir::Body) {
     }
 }
 
-impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
-    fn check_patterns(&self, has_guard: bool, pats: &[P<Pat>]) {
-        check_legality_of_move_bindings(self, has_guard, pats);
-        for pat in pats {
-            check_legality_of_bindings_in_at_patterns(self, pat);
-        }
-    }
-
-    fn report_inlining_errors(&self, patcx: PatternContext, pat_span: Span) {
-        for error in patcx.errors {
-            match error {
+impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
+    fn report_inlining_errors(&self, pat_span: Span) {
+        for error in &self.errors {
+            match *error {
                 PatternError::StaticInPattern(span) => {
                     span_err!(self.tcx.sess, span, E0158,
                               "statics cannot be referenced in patterns");
                 }
-                PatternError::ConstEval(err) => {
-                    report_const_eval_err(self.tcx, &err, pat_span, "pattern");
+                PatternError::ConstEval(ref err) => {
+                    err.report(self.tcx, pat_span, "pattern");
                 }
             }
         }
     }
+}
+
+impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
+    fn check_patterns(&self, has_guard: bool, pats: &[P<Pat>]) {
+        check_legality_of_move_bindings(self, has_guard, pats);
+        for pat in pats {
+            check_legality_of_bindings_in_at_patterns(self, pat);
+        }
+    }
 
     fn check_match(
         &self,
@@ -161,7 +161,7 @@ fn check_match(
                     let mut patcx = PatternContext::new(self.tcx, self.tables);
                     let pattern = expand_pattern(cx, patcx.lower_pattern(&pat));
                     if !patcx.errors.is_empty() {
-                        self.report_inlining_errors(patcx, pat.span);
+                        patcx.report_inlining_errors(pat.span);
                         have_errors = true;
                     }
                     (pattern, &**pat)
index 60eef8dd3bc5fac2f45e0521901ed0a270465f2f..04fc3e68c8ccd9033f3fd0226cfc10e6fe4967b0 100644 (file)
@@ -557,25 +557,6 @@ enum Method { GET, POST }
 See also https://github.com/rust-lang/rust/issues/14587
 "##,
 
-E0080: r##"
-This error indicates that the compiler was unable to sensibly evaluate an
-constant expression that had to be evaluated. Attempting to divide by 0
-or causing integer overflow are two ways to induce this error. For example:
-
-```compile_fail,E0080
-enum Enum {
-    X = (1 << 500),
-    Y = (1 / 0)
-}
-```
-
-Ensure that the expressions given can be evaluated as the desired integer type.
-See the FFI section of the Reference for more information about using a custom
-integer type:
-
-https://doc.rust-lang.org/reference.html#ffi-attributes
-"##,
-
 }
 
 
index 54f5cff16ed6cb584b888d46983820938f5e9d1e..b928bae620b6c08c0ec3d6a12a11ef38de6cc24d 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use rustc::middle::const_val::ConstVal::*;
-use rustc::middle::const_val::ConstVal;
-use self::ErrKind::*;
+use rustc::middle::const_val::ErrKind::*;
+use rustc::middle::const_val::{ConstVal, ConstEvalErr, EvalResult, ErrKind};
 
 use rustc::hir::map as hir_map;
 use rustc::hir::map::blocks::FnLikeNode;
 use rustc::util::common::ErrorReported;
 use rustc::util::nodemap::DefIdMap;
 
-use graphviz::IntoCow;
 use syntax::ast;
 use rustc::hir::{self, Expr};
 use syntax_pos::{Span, DUMMY_SP};
 
-use std::borrow::Cow;
 use std::cmp::Ordering;
 
 use rustc_const_math::*;
-use rustc_errors::DiagnosticBuilder;
 
 macro_rules! signal {
     ($e:expr, $exn:expr) => {
@@ -158,66 +155,6 @@ fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
     }
 }
 
-fn build_const_eval_err<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    err: &ConstEvalErr,
-    primary_span: Span,
-    primary_kind: &str)
-    -> DiagnosticBuilder<'tcx>
-{
-    let mut err = err;
-    while let &ConstEvalErr { kind: ErroneousReferencedConstant(box ref i_err), .. } = err {
-        err = i_err;
-    }
-
-    let mut diag = struct_span_err!(tcx.sess, err.span, E0080, "constant evaluation error");
-    note_const_eval_err(tcx, err, primary_span, primary_kind, &mut diag);
-    diag
-}
-
-pub fn report_const_eval_err<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    err: &ConstEvalErr,
-    primary_span: Span,
-    primary_kind: &str)
-{
-    if let TypeckError = err.kind {
-        return;
-    }
-    build_const_eval_err(tcx, err, primary_span, primary_kind).emit();
-}
-
-pub fn fatal_const_eval_err<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    err: &ConstEvalErr,
-    primary_span: Span,
-    primary_kind: &str)
-    -> !
-{
-    report_const_eval_err(tcx, err, primary_span, primary_kind);
-    tcx.sess.abort_if_errors();
-    unreachable!()
-}
-
-pub fn note_const_eval_err<'a, 'tcx>(
-    _tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    err: &ConstEvalErr,
-    primary_span: Span,
-    primary_kind: &str,
-    diag: &mut DiagnosticBuilder)
-{
-    match err.description() {
-        ConstEvalErrDescription::Simple(message) => {
-            diag.span_label(err.span, &message);
-        }
-    }
-
-    if !primary_span.contains(err.span) {
-        diag.span_note(primary_span,
-                       &format!("for {} here", primary_kind));
-    }
-}
-
 pub struct ConstContext<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
@@ -251,107 +188,7 @@ pub fn eval(&self, e: &Expr) -> EvalResult<'tcx> {
     }
 }
 
-#[derive(Clone, Debug)]
-pub struct ConstEvalErr<'tcx> {
-    pub span: Span,
-    pub kind: ErrKind<'tcx>,
-}
-
-#[derive(Clone, Debug)]
-pub enum ErrKind<'tcx> {
-    CannotCast,
-    MissingStructField,
-    NegateOn(ConstVal<'tcx>),
-    NotOn(ConstVal<'tcx>),
-    CallOn(ConstVal<'tcx>),
-
-    NonConstPath,
-    UnimplementedConstVal(&'static str),
-    ExpectedConstTuple,
-    ExpectedConstStruct,
-    IndexedNonVec,
-    IndexNotUsize,
-    IndexOutOfBounds { len: u64, index: u64 },
-
-    MiscBinaryOp,
-    MiscCatchAll,
-
-    IndexOpFeatureGated,
-    Math(ConstMathErr),
-
-    ErroneousReferencedConstant(Box<ConstEvalErr<'tcx>>),
-
-    TypeckError
-}
-
-impl<'tcx> From<ConstMathErr> for ErrKind<'tcx> {
-    fn from(err: ConstMathErr) -> ErrKind<'tcx> {
-        match err {
-            ConstMathErr::UnsignedNegation => TypeckError,
-            _ => Math(err)
-        }
-    }
-}
-
-#[derive(Clone, Debug)]
-pub enum ConstEvalErrDescription<'a> {
-    Simple(Cow<'a, str>),
-}
-
-impl<'a> ConstEvalErrDescription<'a> {
-    /// Return a one-line description of the error, for lints and such
-    pub fn into_oneline(self) -> Cow<'a, str> {
-        match self {
-            ConstEvalErrDescription::Simple(simple) => simple,
-        }
-    }
-}
-
-impl<'tcx> ConstEvalErr<'tcx> {
-    pub fn description(&self) -> ConstEvalErrDescription {
-        use self::ErrKind::*;
-        use self::ConstEvalErrDescription::*;
-
-        macro_rules! simple {
-            ($msg:expr) => ({ Simple($msg.into_cow()) });
-            ($fmt:expr, $($arg:tt)+) => ({
-                Simple(format!($fmt, $($arg)+).into_cow())
-            })
-        }
-
-        match self.kind {
-            CannotCast => simple!("can't cast this type"),
-            NegateOn(ref const_val) => simple!("negate on {}", const_val.description()),
-            NotOn(ref const_val) => simple!("not on {}", const_val.description()),
-            CallOn(ref const_val) => simple!("call on {}", const_val.description()),
-
-            MissingStructField  => simple!("nonexistent struct field"),
-            NonConstPath        => simple!("non-constant path in constant expression"),
-            UnimplementedConstVal(what) =>
-                simple!("unimplemented constant expression: {}", what),
-            ExpectedConstTuple => simple!("expected constant tuple"),
-            ExpectedConstStruct => simple!("expected constant struct"),
-            IndexedNonVec => simple!("indexing is only supported for arrays"),
-            IndexNotUsize => simple!("indices must be of type `usize`"),
-            IndexOutOfBounds { len, index } => {
-                simple!("index out of bounds: the len is {} but the index is {}",
-                        len, index)
-            }
-
-            MiscBinaryOp => simple!("bad operands for binary"),
-            MiscCatchAll => simple!("unsupported constant expr"),
-            IndexOpFeatureGated => simple!("the index operation on const values is unstable"),
-            Math(ref err) => Simple(err.description().into_cow()),
-
-            ErroneousReferencedConstant(_) => simple!("could not evaluate referenced constant"),
-
-            TypeckError => simple!("type-checking failed"),
-        }
-    }
-}
-
-pub type EvalResult<'tcx> = Result<ConstVal<'tcx>, ConstEvalErr<'tcx>>;
-pub type CastResult<'tcx> = Result<ConstVal<'tcx>, ErrKind<'tcx>>;
+type CastResult<'tcx> = Result<ConstVal<'tcx>, ErrKind<'tcx>>;
 
 fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                                      e: &Expr) -> EvalResult<'tcx> {
@@ -947,14 +784,14 @@ pub fn compare_lit_exprs(&self,
         let a = match self.eval(a) {
             Ok(a) => a,
             Err(e) => {
-                report_const_eval_err(tcx, &e, a.span, "expression");
+                e.report(tcx, a.span, "expression");
                 return Err(ErrorReported);
             }
         };
         let b = match self.eval(b) {
             Ok(b) => b,
             Err(e) => {
-                report_const_eval_err(tcx, &e, b.span, "expression");
+                e.report(tcx, b.span, "expression");
                 return Err(ErrorReported);
             }
         };
@@ -979,8 +816,7 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         Ok(_) |
         Err(ConstEvalErr { kind: TypeckError, .. }) => Err(ErrorReported),
         Err(err) => {
-            let mut diag = build_const_eval_err(
-                tcx, &err, count_expr.span, reason);
+            let mut diag = err.struct_error(tcx, count_expr.span, reason);
 
             if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node {
                 if let Def::Local(..) = path.def {
index 4434a901f9412512f29ed52bcf674f7a15d0b106..fa3161a860498c17dd866295a008c25e86e66e63 100644 (file)
@@ -40,7 +40,6 @@
 extern crate rustc_const_math;
 extern crate rustc_data_structures;
 extern crate rustc_errors;
-extern crate graphviz;
 extern crate syntax_pos;
 
 // NB: This module needs to be declared first so diagnostics are
index bd67dd2e6b25d66518d6e5c786873e769491220b..f20fa27dc225124eca4bd6cd00fa90128e7ffd5a 100644 (file)
@@ -11,7 +11,7 @@
 use eval;
 
 use rustc::lint;
-use rustc::middle::const_val::ConstVal;
+use rustc::middle::const_val::{ConstEvalErr, ConstVal};
 use rustc::mir::{Field, BorrowKind, Mutability};
 use rustc::ty::{self, TyCtxt, AdtDef, Ty, TypeVariants, Region};
 use rustc::ty::subst::{Substs, Kind};
@@ -29,7 +29,7 @@
 #[derive(Clone, Debug)]
 pub enum PatternError<'tcx> {
     StaticInPattern(Span),
-    ConstEval(eval::ConstEvalErr<'tcx>),
+    ConstEval(ConstEvalErr<'tcx>),
 }
 
 #[derive(Copy, Clone, Debug)]
index 3498be9dfdf3205d9dd7b5e1583fe9c9f4077143..d2512ff602a84fb62014c056911a0284f138937c 100644 (file)
@@ -524,7 +524,8 @@ fn get_variant(&self,
         };
 
         if let ty::VariantDiscr::Explicit(def_id) = data.discr {
-            let result = data.evaluated_discr.map_or(Err(()), Ok);
+            // The original crate wouldn't have compiled if this is missing.
+            let result = Ok(data.evaluated_discr.unwrap());
             tcx.maps.monomorphic_const_eval.borrow_mut().insert(def_id, result);
         }
 
index d9b8d04ad386ff6e98833472b4cadfa2212b40ad..595748c8c6fdc4ce26cbface7e4fa393166aaca2 100644 (file)
@@ -17,7 +17,7 @@
 use rustc::hir::map;
 use rustc::hir::def::{Def, CtorKind};
 use rustc::middle::const_val::ConstVal;
-use rustc_const_eval::{ConstContext, fatal_const_eval_err};
+use rustc_const_eval::ConstContext;
 use rustc::ty::{self, AdtKind, VariantDef, Ty};
 use rustc::ty::cast::CastKind as TyCastKind;
 use rustc::hir;
@@ -597,7 +597,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let count = match ConstContext::new(tcx, count).eval(c) {
                 Ok(ConstVal::Integral(ConstInt::Usize(u))) => u,
                 Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other),
-                Err(s) => fatal_const_eval_err(tcx, &s, c.span, "expression")
+                Err(s) => cx.fatal_const_eval_err(&s, c.span, "expression")
             };
 
             ExprKind::Repeat {
index 3eef5d83b8ba0504f2e8946c4f4b5179aeb0bfe7..5f9fb8e1b120f040c57486f2cf285e0ed1b512e7 100644 (file)
@@ -17,8 +17,8 @@
 use hair::*;
 use rustc::mir::transform::MirSource;
 
-use rustc::middle::const_val::ConstVal;
-use rustc_const_eval::{ConstContext, fatal_const_eval_err};
+use rustc::middle::const_val::{ConstEvalErr, ConstVal};
+use rustc_const_eval::ConstContext;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::blocks::FnLikeNode;
@@ -115,10 +115,21 @@ pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
         let tcx = self.tcx.global_tcx();
         match ConstContext::with_tables(tcx, self.tables()).eval(e) {
             Ok(value) => Literal::Value { value: value },
-            Err(s) => fatal_const_eval_err(tcx, &s, e.span, "expression")
+            Err(s) => self.fatal_const_eval_err(&s, e.span, "expression")
         }
     }
 
+    pub fn fatal_const_eval_err(&self,
+        err: &ConstEvalErr<'tcx>,
+        primary_span: Span,
+        primary_kind: &str)
+        -> !
+    {
+        err.report(self.tcx, primary_span, primary_kind);
+        self.tcx.sess.abort_if_errors();
+        unreachable!()
+    }
+
     pub fn trait_method(&mut self,
                         trait_def_id: DefId,
                         method_name: &str,
index 930a13e36bdcaebf3ba853882381c975c3e91ff4..44d3026d80c3e9d20238310d91b7bb65a6804550 100644 (file)
 
 use rustc::dep_graph::DepNode;
 use rustc::ty::cast::CastKind;
-use rustc_const_eval::{ConstEvalErr, ConstContext};
-use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll, Math};
-use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonConstPath};
-use rustc_const_eval::ErrKind::{TypeckError};
+use rustc_const_eval::ConstContext;
+use rustc::middle::const_val::ConstEvalErr;
+use rustc::middle::const_val::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll};
+use rustc::middle::const_val::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonConstPath};
+use rustc::middle::const_val::ErrKind::{TypeckError, Math};
 use rustc_const_math::{ConstMathErr, Op};
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::DefId;
index 07dcb2fc29dc66d4f7db46140fdefd859a2238d6..af477f5a15217bf7ca4c132a5dba9f77a9cb17d1 100644 (file)
@@ -15,7 +15,6 @@ log = "0.3"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
-rustc_const_eval = { path = "../librustc_const_eval" }
 rustc_const_math = { path = "../librustc_const_math" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
index 6b6fa538dc03b655e72d8b3af5c663f1ea01e0c3..7a53a03344fcba2046f7a20e15f5679ffe72e4fa 100644 (file)
@@ -13,9 +13,9 @@
 use llvm;
 use llvm::{SetUnnamedAddr};
 use llvm::{ValueRef, True};
-use rustc_const_eval::ConstEvalErr;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map as hir_map;
+use rustc::middle::const_val::ConstEvalErr;
 use {debuginfo, machine};
 use base;
 use trans_item::TransItem;
index abda358bc4f87c8d36d3c05255f3eade1e302b88..c5383fceb878775586780ffc042e30f9f15ae18a 100644 (file)
@@ -51,7 +51,6 @@
 pub extern crate rustc_llvm as llvm;
 extern crate rustc_platform_intrinsics as intrinsics;
 extern crate rustc_const_math;
-extern crate rustc_const_eval;
 #[macro_use]
 #[no_link]
 extern crate rustc_bitflags;
index caec4789eddce310a244e9c36ddf16eaa1138342..0976859e27f44b7ed8a018922bad67fd9c55bc11 100644 (file)
@@ -9,9 +9,8 @@
 // except according to those terms.
 
 use llvm::{self, ValueRef, BasicBlockRef};
-use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
 use rustc::middle::lang_items;
-use rustc::middle::const_val::ConstInt;
+use rustc::middle::const_val::{ConstEvalErr, ConstInt, ErrKind};
 use rustc::ty::{self, TypeFoldable};
 use rustc::ty::layout::{self, LayoutTyper};
 use rustc::mir;
@@ -363,7 +362,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock,
                         let err = ConstEvalErr{ span: span, kind: err };
                         let mut diag = bcx.tcx().sess.struct_span_warn(
                             span, "this expression will panic at run-time");
-                        note_const_eval_err(bcx.tcx(), &err, span, "expression", &mut diag);
+                        err.note(bcx.tcx(), span, "expression", &mut diag);
                         diag.emit();
                     }
                 }
index 4d5b691c86ebb514def7c8e559a6a2eb39f73b59..37d2b1952f49419df33d4cddc185b7a4a9df3048 100644 (file)
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 use llvm::{self, ValueRef};
-use rustc::middle::const_val::ConstVal;
-use rustc_const_eval::{ErrKind, ConstEvalErr, report_const_eval_err};
+use rustc::middle::const_val::{ConstEvalErr, ConstVal, ErrKind};
 use rustc_const_math::ConstInt::*;
 use rustc_const_math::ConstFloat::*;
 use rustc_const_math::{ConstInt, ConstMathErr};
@@ -327,8 +326,8 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> {
                             }
                         };
 
-                        let err = ConstEvalErr{ span: span, kind: err };
-                        report_const_eval_err(tcx, &err, span, "expression");
+                        let err = ConstEvalErr { span: span, kind: err };
+                        err.report(tcx, span, "expression");
                         failure = Err(err);
                     }
                     target
index f5556bb8382f6540f58bea55168ad96429475e56..4d908f3c94fa58c7e2bda52885741b14ff6dc437 100644 (file)
@@ -28,7 +28,6 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::subst::Substs;
-use rustc_const_eval::fatal_const_eval_err;
 use syntax::ast::{self, NodeId};
 use syntax::attr;
 use type_of;
@@ -82,9 +81,7 @@ pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) {
                     match consts::trans_static(&ccx, m, item.id, &item.attrs) {
                         Ok(_) => { /* Cool, everything's alright. */ },
                         Err(err) => {
-                            // FIXME: shouldn't this be a `span_err`?
-                            fatal_const_eval_err(
-                                ccx.tcx(), &err, item.span, "static");
+                            err.report(ccx.tcx(), item.span, "static");
                         }
                     };
                 } else {
index 649353d52f6aaf29052d3b783a52d38c4c1682f1..4c7979ea3765c31cb0ae653833e99d3206aae84c 100644 (file)
@@ -59,7 +59,7 @@
 use middle::lang_items::SizedTraitLangItem;
 use middle::const_val::ConstVal;
 use middle::resolve_lifetime as rl;
-use rustc_const_eval::{ConstContext, report_const_eval_err};
+use rustc_const_eval::ConstContext;
 use rustc::ty::subst::Substs;
 use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
@@ -587,17 +587,6 @@ fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     tcx.item_predicates(def_id);
 }
 
-fn evaluate_disr_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                body: hir::BodyId)
-                                -> Result<ConstVal<'tcx>, ()> {
-    let e = &tcx.hir.body(body).value;
-    ConstContext::new(tcx, body).eval(e).map_err(|err| {
-        // enum variant evaluation happens before the global constant check
-        // so we need to report the real error
-        report_const_eval_err(tcx, &err, e.span, "enum discriminant");
-    })
-}
-
 fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         def_id: DefId,
                                         variants: &[hir::Variant]) {
@@ -612,9 +601,15 @@ fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         prev_discr = Some(if let Some(e) = variant.node.disr_expr {
             let expr_did = tcx.hir.local_def_id(e.node_id);
             let result = tcx.maps.monomorphic_const_eval.memoize(expr_did, || {
-                evaluate_disr_expr(tcx, e)
+                ConstContext::new(tcx, e).eval(&tcx.hir.body(e).value)
             });
 
+            // enum variant evaluation happens before the global constant check
+            // so we need to report the real error
+            if let Err(ref err) = result {
+                err.report(tcx, variant.span, "enum discriminant");
+            }
+
             match result {
                 Ok(ConstVal::Integral(x)) => Some(x),
                 _ => None