Move the Lrc outside the error type and name the fields

This commit is contained in:
Oliver Schneider 2018-06-25 17:41:20 +02:00
parent 6e5951c734
commit 6005b0ad2f
12 changed files with 46 additions and 33 deletions

View File

@ -505,7 +505,8 @@ impl_stable_hash_for!(struct ty::Const<'tcx> {
impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> {
span,
data
stacktrace,
error
});
impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {

View File

@ -20,7 +20,7 @@ use syntax::ast;
use rustc_data_structures::sync::Lrc;
pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>;
pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>;
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
pub enum ConstVal<'tcx> {
@ -31,7 +31,8 @@ pub enum ConstVal<'tcx> {
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ConstEvalErr<'tcx> {
pub span: Span,
pub data: Lrc<(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>)>,
pub error: ::mir::interpret::EvalError<'tcx>,
pub stacktrace: Vec<FrameInfo>,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
@ -81,7 +82,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
message: &str,
lint_root: Option<ast::NodeId>,
) -> Option<DiagnosticBuilder<'tcx>> {
match self.data.0.kind {
match self.error.kind {
::mir::interpret::EvalErrorKind::TypeckError |
::mir::interpret::EvalErrorKind::TooGeneric |
::mir::interpret::EvalErrorKind::CheckMatchError |
@ -93,7 +94,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
}
trace!("reporting const eval failure at {:?}", self.span);
let mut err = if let Some(lint_root) = lint_root {
let node_id = self.data.1
let node_id = self.stacktrace
.iter()
.rev()
.filter_map(|frame| frame.lint_root)
@ -108,8 +109,8 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
} else {
struct_error(tcx, message)
};
err.span_label(self.span, self.data.0.to_string());
for FrameInfo { span, location, .. } in &self.data.1 {
err.span_label(self.span, self.error.to_string());
for FrameInfo { span, location, .. } in &self.stacktrace {
err.span_label(*span, format!("inside call to `{}`", location));
}
Some(err)

View File

@ -4,6 +4,7 @@ use mir;
use middle::const_val::ConstEvalErr;
use ty::{FnSig, Ty, layout};
use ty::layout::{Size, Align};
use rustc_data_structures::sync::Lrc;
use super::{
Pointer, Lock, AccessKind
@ -155,7 +156,7 @@ pub enum EvalErrorKind<'tcx, O> {
CheckMatchError,
/// Cannot compute this constant because it depends on another one
/// which already produced an error
ReferencedConstant(ConstEvalErr<'tcx>),
ReferencedConstant(Lrc<ConstEvalErr<'tcx>>),
GeneratorResumedAfterReturn,
GeneratorResumedAfterPanic,
}

View File

@ -499,12 +499,12 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
CodeSelectionError(ConstEvalFailure(err)))
}
} else {
let err = EvalErrorKind::TooGeneric.into();
ProcessResult::Error(
CodeSelectionError(ConstEvalFailure(ConstEvalErr {
span: obligation.cause.span,
data: (err, vec![]).into(),
}))
error: EvalErrorKind::TooGeneric.into(),
stacktrace: vec![],
}.into()))
)
}
},

View File

@ -381,7 +381,7 @@ pub enum SelectionError<'tcx> {
ty::PolyTraitRef<'tcx>,
ty::error::TypeError<'tcx>),
TraitNotObjectSafe(DefId),
ConstEvalFailure(ConstEvalErr<'tcx>),
ConstEvalFailure(Lrc<ConstEvalErr<'tcx>>),
Overflow,
}

View File

@ -172,7 +172,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
})
}
super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
super::ConstEvalFailure(ref err) => tcx.lift(err).map(super::ConstEvalFailure),
super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
err.into(),
)),
super::Overflow => bug!(), // FIXME: ape ConstEvalFailure?
}
}

View File

@ -18,7 +18,6 @@ use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::sync::Lrc;
use mir::interpret;
use std::rc::Rc;
@ -462,10 +461,11 @@ 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.data.0).map(|data| {
tcx.lift(&self.error).map(|error| {
ConstEvalErr {
span: self.span,
data: Lrc::new((data, self.data.1.clone())),
stacktrace: self.stacktrace.clone(),
error,
}
})
}
@ -579,7 +579,7 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
TypeckError => TypeckError,
TooGeneric => TooGeneric,
CheckMatchError => CheckMatchError,
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?),
ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(&**err)?.into()),
OverflowNeg => OverflowNeg,
Overflow(op) => Overflow(op),
DivisionByZero => DivisionByZero,

View File

@ -14,6 +14,7 @@ use rustc_mir::interpret::{read_target_uint, const_val_field};
use rustc::hir::def_id::DefId;
use rustc::mir;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::sync::Lrc;
use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size};
@ -117,7 +118,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
pub fn codegen_static_initializer<'a, 'tcx>(
cx: &CodegenCx<'a, 'tcx>,
def_id: DefId)
-> Result<ValueRef, ConstEvalErr<'tcx>>
-> Result<ValueRef, Lrc<ConstEvalErr<'tcx>>>
{
let instance = ty::Instance::mono(cx.tcx, def_id);
let cid = GlobalId {
@ -139,7 +140,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
&mut self,
bx: &Builder<'a, 'tcx>,
constant: &'tcx ty::Const<'tcx>,
) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> {
) -> Result<ConstValue<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
match constant.val {
ConstVal::Unevaluated(def_id, ref substs) => {
let tcx = bx.tcx();
@ -160,7 +161,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
&mut self,
bx: &Builder<'a, 'tcx>,
constant: &mir::Constant<'tcx>,
) -> Result<ConstValue<'tcx>, ConstEvalErr<'tcx>> {
) -> Result<ConstValue<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
match constant.literal {
mir::Literal::Promoted { index } => {
let param_env = ty::ParamEnv::reveal_all();
@ -189,7 +190,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
ty::TyArray(_, n) => n.unwrap_usize(bx.tcx()),
ref other => bug!("invalid simd shuffle type: {}", other),
};
let values: Result<Vec<ValueRef>, _> = (0..fields).map(|field| {
let values: Result<Vec<ValueRef>, Lrc<_>> = (0..fields).map(|field| {
let field = const_val_field(
bx.tcx(),
ty::ParamEnv::reveal_all(),

View File

@ -15,6 +15,7 @@ use rustc::mir::interpret::ConstValue;
use rustc::ty;
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::sync::Lrc;
use base;
use common::{self, CodegenCx, C_null, C_undef, C_usize};
@ -97,7 +98,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
pub fn from_const(bx: &Builder<'a, 'tcx>,
val: ConstValue<'tcx>,
ty: ty::Ty<'tcx>)
-> Result<OperandRef<'tcx>, ConstEvalErr<'tcx>> {
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
let layout = bx.cx.layout_of(ty);
if layout.is_zst() {

View File

@ -104,7 +104,8 @@ pub fn value_to_const_value<'tcx>(
let (frames, span) = ecx.generate_stacktrace(None);
let err = ConstEvalErr {
span,
data: (err, frames).into(),
error: err,
stacktrace: frames,
};
err.report_as_error(
ecx.tcx,
@ -466,9 +467,10 @@ pub fn const_val_field<'a, 'tcx>(
result.map_err(|err| {
let (trace, span) = ecx.generate_stacktrace(None);
ConstEvalErr {
data: (err, trace).into(),
error: err,
stacktrace: trace,
span,
}
}.into()
})
}
@ -537,9 +539,10 @@ pub fn const_eval_provider<'a, 'tcx>(
// Do match-check before building MIR
if tcx.check_match(def_id).is_err() {
return Err(ConstEvalErr {
data: (EvalErrorKind::CheckMatchError.into(), Vec::new()).into(),
error: EvalErrorKind::CheckMatchError.into(),
stacktrace: vec![],
span,
});
}.into());
}
if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(id) {
@ -549,9 +552,10 @@ 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 {
data: (EvalErrorKind::TypeckError.into(), Vec::new()).into(),
error: EvalErrorKind::CheckMatchError.into(),
stacktrace: vec![],
span,
});
}.into());
}
};
@ -564,13 +568,14 @@ pub fn const_eval_provider<'a, 'tcx>(
}).map_err(|err| {
let (trace, span) = ecx.generate_stacktrace(None);
let err = ConstEvalErr {
data: (err, trace).into(),
error: err,
stacktrace: trace,
span,
};
if tcx.is_static(def_id).is_some() {
err.report_as_error(ecx.tcx, "could not evaluate static initializer");
}
err
err.into()
})
}

View File

@ -1210,7 +1210,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Ok(val) => collect_const(tcx, val, instance.substs, output),
Err(err) => {
use rustc::mir::interpret::EvalErrorKind;
if let EvalErrorKind::ReferencedConstant(_) = err.data.0.kind {
if let EvalErrorKind::ReferencedConstant(_) = err.error.kind {
err.report_as_error(
tcx.at(mir.promoted[i].span),
"erroneous constant used",

View File

@ -145,7 +145,8 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
let (frames, span) = self.ecx.generate_stacktrace(None);
let err = ConstEvalErr {
span,
data: (err, frames).into(),
error: err,
stacktrace: frames,
};
err.report_as_lint(
self.ecx.tcx,