miri: backtraces with instances
This commit is contained in:
parent
126a0e2aad
commit
57a7c85f93
3 changed files with 31 additions and 21 deletions
|
@ -387,10 +387,10 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
|
|||
TooGeneric
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct mir::interpret::FrameInfo {
|
||||
impl_stable_hash_for!(struct mir::interpret::FrameInfo<'tcx> {
|
||||
span,
|
||||
lint_root,
|
||||
location
|
||||
instance
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
|
||||
use std::{fmt, env};
|
||||
|
||||
use hir::map::definitions::DefPathData;
|
||||
use mir;
|
||||
use ty::{Ty, layout};
|
||||
use ty::{self, Ty, layout};
|
||||
use ty::layout::{Size, Align, LayoutError};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
|
@ -19,7 +20,6 @@ use super::{Pointer, Scalar};
|
|||
|
||||
use backtrace::Backtrace;
|
||||
|
||||
use ty;
|
||||
use ty::query::TyCtxtAt;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
|
@ -52,16 +52,30 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
|
|||
pub struct ConstEvalErr<'tcx> {
|
||||
pub span: Span,
|
||||
pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>,
|
||||
pub stacktrace: Vec<FrameInfo>,
|
||||
pub stacktrace: Vec<FrameInfo<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct FrameInfo {
|
||||
pub struct FrameInfo<'tcx> {
|
||||
pub span: Span,
|
||||
pub location: String,
|
||||
pub instance: ty::Instance<'tcx>,
|
||||
pub lint_root: Option<ast::NodeId>,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Display for FrameInfo<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ty::tls::with(|tcx| {
|
||||
if tcx.def_key(self.instance.def_id()).disambiguated_data.data
|
||||
== DefPathData::ClosureExpr
|
||||
{
|
||||
write!(f, "inside call to closure")
|
||||
} else {
|
||||
write!(f, "inside call to `{}`", self.instance)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||
pub fn struct_error(&self,
|
||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||
|
@ -135,8 +149,13 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
|||
struct_error(tcx, message)
|
||||
};
|
||||
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));
|
||||
// Skip the last, which is just the environment of the constant. The stacktrace
|
||||
// is sometimes empty because we create "fake" eval contexts in CTFE to do work
|
||||
// on constant values.
|
||||
if self.stacktrace.len() > 0 {
|
||||
for frame_info in &self.stacktrace[..self.stacktrace.len()-1] {
|
||||
err.span_label(frame_info.span, frame_info.to_string());
|
||||
}
|
||||
}
|
||||
Ok(err)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use std::mem;
|
|||
use syntax::source_map::{self, Span, DUMMY_SP};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::map::definitions::DefPathData;
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::{
|
||||
self, Size, Align, HasDataLayout, LayoutOf, TyLayout
|
||||
|
@ -654,11 +653,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
}
|
||||
}
|
||||
|
||||
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo> {
|
||||
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
|
||||
let mut last_span = None;
|
||||
let mut frames = Vec::new();
|
||||
// skip 1 because the last frame is just the environment of the constant
|
||||
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() {
|
||||
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().rev() {
|
||||
// make sure we don't emit frames that are duplicates of the previous
|
||||
if explicit_span == Some(span) {
|
||||
last_span = Some(span);
|
||||
|
@ -671,13 +669,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
} else {
|
||||
last_span = Some(span);
|
||||
}
|
||||
let location = if self.tcx.def_key(instance.def_id()).disambiguated_data.data
|
||||
== DefPathData::ClosureExpr
|
||||
{
|
||||
"closure".to_owned()
|
||||
} else {
|
||||
instance.to_string()
|
||||
};
|
||||
let block = &mir.basic_blocks()[block];
|
||||
let source_info = if stmt < block.statements.len() {
|
||||
block.statements[stmt].source_info
|
||||
|
@ -688,7 +679,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
|
||||
mir::ClearCrossCrate::Clear => None,
|
||||
};
|
||||
frames.push(FrameInfo { span, location, lint_root });
|
||||
frames.push(FrameInfo { span, instance, lint_root });
|
||||
}
|
||||
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
|
||||
frames
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue