rustc_const_eval: move ConstEvalErr to the rustc crate.

This commit is contained in:
Eduard-Mihai Burtescu 2017-04-13 16:40:03 +03:00
parent d5cf1cb64c
commit 8854164d0c
21 changed files with 245 additions and 258 deletions

2
src/Cargo.lock generated
View 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",

View 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

View 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 hir::def_id::DefId;
use ty::subst::Substs;
use rustc_const_math::*;
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 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();
}
}

View 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 @@ 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>,

View 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" }

View File

@ -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,6 +106,22 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
}
}
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(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);
@ -116,20 +130,6 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
}
}
fn report_inlining_errors(&self, patcx: PatternContext, pat_span: Span) {
for error in patcx.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");
}
}
}
}
fn check_match(
&self,
scrut: &hir::Expr,
@ -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)

View File

@ -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
"##,
}

View 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;
@ -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 {

View File

@ -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

View 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 @@ use syntax_pos::Span;
#[derive(Clone, Debug)]
pub enum PatternError<'tcx> {
StaticInPattern(Span),
ConstEval(eval::ConstEvalErr<'tcx>),
ConstEval(ConstEvalErr<'tcx>),
}
#[derive(Copy, Clone, Debug)]

View File

@ -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);
}

View File

@ -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 {

View 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 @@ 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,

View File

@ -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;

View 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" }

View File

@ -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;

View File

@ -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;

View 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 @@ 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();
}
}

View 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 @@ 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

View File

@ -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 {

View File

@ -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