miri: backtraces with instances
This commit is contained in:
parent
126a0e2aad
commit
57a7c85f93
@ -387,10 +387,10 @@ fn hash_stable<W: StableHasherResult>(
|
||||
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 backtrace::Backtrace;
|
||||
|
||||
use ty;
|
||||
use ty::query::TyCtxtAt;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
@ -52,16 +52,30 @@ pub fn assert_reported(self) {
|
||||
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 @@ fn struct_generic(
|
||||
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 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 @@ pub fn dump_place(&self, place: Place<M::PointerTag>) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo>
|
||||
} 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 @@ pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo>
|
||||
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…
Reference in New Issue
Block a user