Eliminate old CTFE's ErrKind
This commit is contained in:
parent
58fdac638e
commit
6f8fe4eaef
@ -505,7 +505,7 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> {
|
||||
span,
|
||||
kind
|
||||
data
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {
|
||||
@ -514,29 +514,6 @@ impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {
|
||||
location
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ::middle::const_val::ErrKind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
use middle::const_val::ErrKind::*;
|
||||
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
TypeckError |
|
||||
CouldNotResolve |
|
||||
CheckMatchError => {
|
||||
// nothing to do
|
||||
}
|
||||
Miri(ref err, ref trace) => {
|
||||
err.hash_stable(hcx, hasher);
|
||||
trace.hash_stable(hcx, hasher);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
||||
impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
|
||||
|
||||
@ -593,6 +570,8 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||
ReadFromReturnPointer |
|
||||
UnimplementedTraitSelection |
|
||||
TypeckError |
|
||||
ResolutionFailed |
|
||||
CheckMatchError |
|
||||
DerefFunctionPointer |
|
||||
ExecuteMemory |
|
||||
OverflowNeg |
|
||||
|
@ -33,16 +33,7 @@ pub enum ConstVal<'tcx> {
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct ConstEvalErr<'tcx> {
|
||||
pub span: Span,
|
||||
pub kind: Lrc<ErrKind<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum ErrKind<'tcx> {
|
||||
|
||||
CouldNotResolve,
|
||||
TypeckError,
|
||||
CheckMatchError,
|
||||
Miri(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>),
|
||||
pub data: Lrc<(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
@ -69,25 +60,6 @@ impl<'a, 'tcx> ConstEvalErrDescription<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
pub fn description(&'a self) -> ConstEvalErrDescription<'a, 'tcx> {
|
||||
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 {
|
||||
CouldNotResolve => simple!("could not resolve"),
|
||||
TypeckError => simple!("type-checking failed"),
|
||||
CheckMatchError => simple!("match-checking failed"),
|
||||
Miri(ref err, ref trace) => Backtrace(err, trace),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
message: &str)
|
||||
@ -127,24 +99,19 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
message: &str,
|
||||
lint_root: Option<ast::NodeId>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
let (msg, frames): (_, &[_]) = match *self.kind {
|
||||
ErrKind::TypeckError | ErrKind::CheckMatchError => return None,
|
||||
ErrKind::Miri(ref miri, ref frames) => {
|
||||
match miri.kind {
|
||||
::mir::interpret::EvalErrorKind::TypeckError |
|
||||
::mir::interpret::EvalErrorKind::Layout(_) => return None,
|
||||
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
|
||||
inner.struct_generic(tcx, "referenced constant", lint_root)?.emit();
|
||||
(miri.to_string(), frames)
|
||||
},
|
||||
_ => (miri.to_string(), frames),
|
||||
}
|
||||
}
|
||||
_ => (self.description().into_oneline().to_string(), &[]),
|
||||
};
|
||||
match self.data.0.kind {
|
||||
::mir::interpret::EvalErrorKind::TypeckError |
|
||||
::mir::interpret::EvalErrorKind::ResolutionFailed |
|
||||
::mir::interpret::EvalErrorKind::CheckMatchError |
|
||||
::mir::interpret::EvalErrorKind::Layout(_) => return None,
|
||||
::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
|
||||
inner.struct_generic(tcx, "referenced constant", lint_root)?.emit();
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
trace!("reporting const eval failure at {:?}", self.span);
|
||||
let mut err = if let Some(lint_root) = lint_root {
|
||||
let node_id = frames
|
||||
let node_id = self.data.1
|
||||
.iter()
|
||||
.rev()
|
||||
.filter_map(|frame| frame.lint_root)
|
||||
@ -159,8 +126,8 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
} else {
|
||||
struct_error(tcx, message)
|
||||
};
|
||||
err.span_label(self.span, msg);
|
||||
for FrameInfo { span, location, .. } in frames {
|
||||
err.span_label(self.span, self.data.0.to_string());
|
||||
for FrameInfo { span, location, .. } in &self.data.1 {
|
||||
err.span_label(*span, format!("inside call to `{}`", location));
|
||||
}
|
||||
Some(err)
|
||||
|
@ -150,6 +150,9 @@ pub enum EvalErrorKind<'tcx, O> {
|
||||
UnimplementedTraitSelection,
|
||||
/// Abort in case type errors are reached
|
||||
TypeckError,
|
||||
/// Resolution can fail if we are in a too generic context
|
||||
ResolutionFailed,
|
||||
CheckMatchError,
|
||||
/// Cannot compute this constant because it depends on another one
|
||||
/// which already produced an error
|
||||
ReferencedConstant(ConstEvalErr<'tcx>),
|
||||
@ -268,6 +271,10 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
|
||||
"there were unresolved type arguments during trait selection",
|
||||
TypeckError =>
|
||||
"encountered constants with type errors, stopping evaluation",
|
||||
ResolutionFailed =>
|
||||
"encountered overly generic constant",
|
||||
CheckMatchError =>
|
||||
"match checking failed",
|
||||
ReferencedConstant(_) =>
|
||||
"referenced constant has errors",
|
||||
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
||||
|
@ -16,7 +16,8 @@ use rustc_data_structures::obligation_forest::{Error, ForestObligation, Obligati
|
||||
use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
|
||||
use std::marker::PhantomData;
|
||||
use hir::def_id::DefId;
|
||||
use middle::const_val::{ConstEvalErr, ErrKind};
|
||||
use middle::const_val::ConstEvalErr;
|
||||
use mir::interpret::EvalErrorKind;
|
||||
|
||||
use super::CodeAmbiguity;
|
||||
use super::CodeProjectionError;
|
||||
@ -498,10 +499,11 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
|
||||
CodeSelectionError(ConstEvalFailure(err)))
|
||||
}
|
||||
} else {
|
||||
let err = EvalErrorKind::ResolutionFailed.into();
|
||||
ProcessResult::Error(
|
||||
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
|
||||
span: obligation.cause.span,
|
||||
kind: ErrKind::CouldNotResolve.into(),
|
||||
data: (err, Vec::new()).into(),
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! hand, though we've recently added some macros (e.g.,
|
||||
//! `BraceStructLiftImpl!`) to help with the tedium.
|
||||
|
||||
use middle::const_val::{self, ConstVal, ConstEvalErr};
|
||||
use middle::const_val::{ConstVal, ConstEvalErr};
|
||||
use ty::{self, Lift, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||
@ -462,10 +462,10 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
|
||||
impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
|
||||
type Lifted = ConstEvalErr<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&*self.kind).map(|kind| {
|
||||
tcx.lift(&self.data.0).map(|data| {
|
||||
ConstEvalErr {
|
||||
span: self.span,
|
||||
kind: Lrc::new(kind),
|
||||
data: Lrc::new((data, self.data.1.clone())),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -577,6 +577,8 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
|
||||
PathNotFound(ref v) => PathNotFound(v.clone()),
|
||||
UnimplementedTraitSelection => UnimplementedTraitSelection,
|
||||
TypeckError => TypeckError,
|
||||
ResolutionFailed => ResolutionFailed,
|
||||
CheckMatchError => CheckMatchError,
|
||||
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?),
|
||||
OverflowNeg => OverflowNeg,
|
||||
Overflow(op) => Overflow(op),
|
||||
@ -588,20 +590,6 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for const_val::ErrKind<'a> {
|
||||
type Lifted = const_val::ErrKind<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
use middle::const_val::ErrKind::*;
|
||||
|
||||
Some(match *self {
|
||||
CouldNotResolve => CouldNotResolve,
|
||||
TypeckError => TypeckError,
|
||||
CheckMatchError => CheckMatchError,
|
||||
Miri(ref e, ref frames) => return tcx.lift(e).map(|e| Miri(e, frames.clone())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::layout::LayoutError<'a> {
|
||||
type Lifted = ty::layout::LayoutError<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
|
@ -1,6 +1,5 @@
|
||||
use rustc::hir;
|
||||
use rustc::middle::const_val::{ConstEvalErr, ErrKind};
|
||||
use rustc::middle::const_val::ErrKind::{TypeckError, CheckMatchError};
|
||||
use rustc::middle::const_val::{ConstEvalErr};
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, TyCtxt, Ty, Instance};
|
||||
use rustc::ty::layout::{self, LayoutOf, Primitive};
|
||||
@ -18,7 +17,6 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, Memo
|
||||
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
@ -106,7 +104,7 @@ pub fn value_to_const_value<'tcx>(
|
||||
let (frames, span) = ecx.generate_stacktrace(None);
|
||||
let err = ConstEvalErr {
|
||||
span,
|
||||
kind: ErrKind::Miri(err, frames).into(),
|
||||
data: (err, frames).into(),
|
||||
};
|
||||
err.report_as_error(
|
||||
ecx.tcx,
|
||||
@ -467,9 +465,8 @@ pub fn const_val_field<'a, 'tcx>(
|
||||
})();
|
||||
result.map_err(|err| {
|
||||
let (trace, span) = ecx.generate_stacktrace(None);
|
||||
let err = ErrKind::Miri(err, trace);
|
||||
ConstEvalErr {
|
||||
kind: err.into(),
|
||||
data: (err, trace).into(),
|
||||
span,
|
||||
}
|
||||
})
|
||||
@ -540,7 +537,7 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||
// Do match-check before building MIR
|
||||
if tcx.check_match(def_id).is_err() {
|
||||
return Err(ConstEvalErr {
|
||||
kind: Lrc::new(CheckMatchError),
|
||||
data: (EvalErrorKind::CheckMatchError.into(), Vec::new()).into(),
|
||||
span,
|
||||
});
|
||||
}
|
||||
@ -552,7 +549,7 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||
// Do not continue into miri if typeck errors occurred; it will fail horribly
|
||||
if tables.tainted_by_errors {
|
||||
return Err(ConstEvalErr {
|
||||
kind: Lrc::new(TypeckError),
|
||||
data: (EvalErrorKind::TypeckError.into(), Vec::new()).into(),
|
||||
span,
|
||||
});
|
||||
}
|
||||
@ -566,9 +563,8 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||
Ok(value_to_const_value(&ecx, val, miri_ty))
|
||||
}).map_err(|err| {
|
||||
let (trace, span) = ecx.generate_stacktrace(None);
|
||||
let err = ErrKind::Miri(err, trace);
|
||||
let err = ConstEvalErr {
|
||||
kind: err.into(),
|
||||
data: (err, trace).into(),
|
||||
span,
|
||||
};
|
||||
if tcx.is_static(def_id).is_some() {
|
||||
|
@ -280,7 +280,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
|
||||
).ok_or_else(|| EvalErrorKind::ResolutionFailed.into())
|
||||
}
|
||||
|
||||
pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||
@ -739,7 +739,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| EvalErrorKind::TypeckError.into());
|
||||
).ok_or_else(|| EvalErrorKind::ResolutionFailed.into());
|
||||
let fn_ptr = self.memory.create_fn_alloc(instance?);
|
||||
let valty = ValTy {
|
||||
value: Value::Scalar(fn_ptr.into()),
|
||||
|
@ -285,10 +285,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|_| {
|
||||
self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
|
||||
// no need to report anything, the const_eval call takes care of that for statics
|
||||
assert!(self.tcx.is_static(def_id).is_some());
|
||||
EvalErrorKind::TypeckError.into()
|
||||
EvalErrorKind::ReferencedConstant(err).into()
|
||||
}).map(|val| {
|
||||
let const_val = match val.val {
|
||||
ConstVal::Value(val) => val,
|
||||
|
@ -1209,15 +1209,12 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
match tcx.const_eval(param_env.and(cid)) {
|
||||
Ok(val) => collect_const(tcx, val, instance.substs, output),
|
||||
Err(err) => {
|
||||
use rustc::middle::const_val::ErrKind;
|
||||
use rustc::mir::interpret::EvalErrorKind;
|
||||
if let ErrKind::Miri(ref miri, ..) = *err.kind {
|
||||
if let EvalErrorKind::ReferencedConstant(_) = miri.kind {
|
||||
err.report_as_error(
|
||||
tcx.at(mir.promoted[i].span),
|
||||
"erroneous constant used",
|
||||
);
|
||||
}
|
||||
if let EvalErrorKind::ReferencedConstant(_) = err.data.0.kind {
|
||||
err.report_as_error(
|
||||
tcx.at(mir.promoted[i].span),
|
||||
"erroneous constant used",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local
|
||||
use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind};
|
||||
use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
|
||||
use rustc::mir::visit::{Visitor, PlaceContext};
|
||||
use rustc::middle::const_val::{ConstVal, ConstEvalErr, ErrKind};
|
||||
use rustc::middle::const_val::{ConstVal, ConstEvalErr};
|
||||
use rustc::ty::{TyCtxt, self, Instance};
|
||||
use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult};
|
||||
use interpret::EvalContext;
|
||||
@ -145,7 +145,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
let (frames, span) = self.ecx.generate_stacktrace(None);
|
||||
let err = ConstEvalErr {
|
||||
span,
|
||||
kind: ErrKind::Miri(err, frames).into(),
|
||||
data: (err, frames).into(),
|
||||
};
|
||||
err.report_as_lint(
|
||||
self.ecx.tcx,
|
||||
|
Loading…
Reference in New Issue
Block a user