diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-13 16:40:03 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-16 01:31:06 +0300 |
| commit | 8854164d0cda3c90f6c3c774d8acf891599e4da3 (patch) | |
| tree | bacca832c1ebe509413bd5385be707e25e9372a2 /src | |
| parent | d5cf1cb64cd1948a8c289e29838716f03d49d5aa (diff) | |
| download | rust-8854164d0cda3c90f6c3c774d8acf891599e4da3.tar.gz rust-8854164d0cda3c90f6c3c774d8acf891599e4da3.zip | |
rustc_const_eval: move ConstEvalErr to the rustc crate.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Cargo.lock | 2 | ||||
| -rw-r--r-- | src/librustc/diagnostics.rs | 19 | ||||
| -rw-r--r-- | src/librustc/middle/const_val.rs | 164 | ||||
| -rw-r--r-- | src/librustc/ty/maps.rs | 4 | ||||
| -rw-r--r-- | src/librustc_const_eval/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 32 | ||||
| -rw-r--r-- | src/librustc_const_eval/diagnostics.rs | 19 | ||||
| -rw-r--r-- | src/librustc_const_eval/eval.rs | 176 | ||||
| -rw-r--r-- | src/librustc_const_eval/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc_const_eval/pattern.rs | 4 | ||||
| -rw-r--r-- | src/librustc_metadata/decoder.rs | 3 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/mod.rs | 17 | ||||
| -rw-r--r-- | src/librustc_passes/consts.rs | 9 | ||||
| -rw-r--r-- | src/librustc_trans/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/librustc_trans/consts.rs | 2 | ||||
| -rw-r--r-- | src/librustc_trans/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc_trans/mir/block.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trans/mir/constant.rs | 7 | ||||
| -rw-r--r-- | src/librustc_trans/trans_item.rs | 5 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 21 |
21 files changed, 242 insertions, 255 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock index 1fa256197ce..c4b5366d4a3 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -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", diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 5a0fbf8efb7..8a391f9cde3 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -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 diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index d81f89827d9..9315f7f5808 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -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 @@ impl<'tcx> ConstVal<'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 => 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(); + } +} diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 868ccad8a3a..e9eb5e97582 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -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 @@ define_maps! { <'tcx> /// 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>, diff --git a/src/librustc_const_eval/Cargo.toml b/src/librustc_const_eval/Cargo.toml index 907410f74dc..bbc61480824 100644 --- a/src/librustc_const_eval/Cargo.toml +++ b/src/librustc_const_eval/Cargo.toml @@ -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" } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 9d55281d019..f1ab6a00aa2 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -14,8 +14,6 @@ use _match::WitnessPreference::*; 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 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { } } -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 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { 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) diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs index 60eef8dd3bc..04fc3e68c8c 100644 --- a/src/librustc_const_eval/diagnostics.rs +++ b/src/librustc_const_eval/diagnostics.rs @@ -557,25 +557,6 @@ The `op_string_ref` binding has type `&Option<&String>` in both cases. 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 -"##, - } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 54f5cff16ed..b928bae620b 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -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; @@ -24,16 +24,13 @@ use rustc::traits::Reveal; 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 @@ impl<'a, 'tcx> ConstContext<'a, '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 @@ impl<'a, 'tcx> ConstContext<'a, 'tcx> { 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 { diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 4434a901f94..fa3161a8604 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -40,7 +40,6 @@ extern crate rustc_back; 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 diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index bd67dd2e6b2..f20fa27dc22 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -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 @@ use syntax_pos::Span; #[derive(Clone, Debug)] pub enum PatternError<'tcx> { StaticInPattern(Span), - ConstEval(eval::ConstEvalErr<'tcx>), + ConstEval(ConstEvalErr<'tcx>), } #[derive(Copy, Clone, Debug)] diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 3498be9dfdf..d2512ff602a 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -524,7 +524,8 @@ impl<'a, 'tcx> CrateMetadata { }; 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); } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index d9b8d04ad38..595748c8c6f 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -17,7 +17,7 @@ use hair::cx::to_ref::ToRef; 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 { diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 3eef5d83b8b..5f9fb8e1b12 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -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 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, '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, diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 930a13e36bd..44d3026d80c 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -26,10 +26,11 @@ 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; diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 07dcb2fc29d..af477f5a152 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -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" } diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 6b6fa538dc0..7a53a03344f 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -13,9 +13,9 @@ use back::symbol_names; 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; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index abda358bc4f..c5383fceb87 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -51,7 +51,6 @@ extern crate rustc_incremental; 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; diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index caec4789edd..0976859e27f 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -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 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { 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(); } } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 4d5b691c86e..37d2b1952f4 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -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 @@ impl<'a, 'tcx> MirConstContext<'a, '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 diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index f5556bb8382..4d908f3c94f 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -28,7 +28,6 @@ use rustc::hir; 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 @@ impl<'a, 'tcx> TransItem<'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 { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 649353d52f6..4c7979ea376 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -59,7 +59,7 @@ use constrained_type_params as ctp; 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 |
