Move the Lrc outside the error type and name the fields
This commit is contained in:
parent
6e5951c734
commit
6005b0ad2f
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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()))
|
||||
)
|
||||
}
|
||||
},
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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?
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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() {
|
||||
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user