miri: backtraces with instances
This commit is contained in:
parent
126a0e2aad
commit
57a7c85f93
@ -387,10 +387,10 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
|
|||||||
TooGeneric
|
TooGeneric
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct mir::interpret::FrameInfo {
|
impl_stable_hash_for!(struct mir::interpret::FrameInfo<'tcx> {
|
||||||
span,
|
span,
|
||||||
lint_root,
|
lint_root,
|
||||||
location
|
instance
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
use std::{fmt, env};
|
use std::{fmt, env};
|
||||||
|
|
||||||
|
use hir::map::definitions::DefPathData;
|
||||||
use mir;
|
use mir;
|
||||||
use ty::{Ty, layout};
|
use ty::{self, Ty, layout};
|
||||||
use ty::layout::{Size, Align, LayoutError};
|
use ty::layout::{Size, Align, LayoutError};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
@ -19,7 +20,6 @@ use super::{Pointer, Scalar};
|
|||||||
|
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
|
|
||||||
use ty;
|
|
||||||
use ty::query::TyCtxtAt;
|
use ty::query::TyCtxtAt;
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
|
||||||
@ -52,16 +52,30 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
|
|||||||
pub struct ConstEvalErr<'tcx> {
|
pub struct ConstEvalErr<'tcx> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>,
|
pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>,
|
||||||
pub stacktrace: Vec<FrameInfo>,
|
pub stacktrace: Vec<FrameInfo<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||||
pub struct FrameInfo {
|
pub struct FrameInfo<'tcx> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub location: String,
|
pub instance: ty::Instance<'tcx>,
|
||||||
pub lint_root: Option<ast::NodeId>,
|
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> {
|
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
||||||
pub fn struct_error(&self,
|
pub fn struct_error(&self,
|
||||||
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
|
||||||
@ -135,8 +149,13 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
|
|||||||
struct_error(tcx, message)
|
struct_error(tcx, message)
|
||||||
};
|
};
|
||||||
err.span_label(self.span, self.error.to_string());
|
err.span_label(self.span, self.error.to_string());
|
||||||
for FrameInfo { span, location, .. } in &self.stacktrace {
|
// Skip the last, which is just the environment of the constant. The stacktrace
|
||||||
err.span_label(*span, format!("inside call to `{}`", location));
|
// 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)
|
Ok(err)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ use std::mem;
|
|||||||
use syntax::source_map::{self, Span, DUMMY_SP};
|
use syntax::source_map::{self, Span, DUMMY_SP};
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::Def;
|
||||||
use rustc::hir::map::definitions::DefPathData;
|
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::layout::{
|
use rustc::ty::layout::{
|
||||||
self, Size, Align, HasDataLayout, LayoutOf, TyLayout
|
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 last_span = None;
|
||||||
let mut frames = Vec::new();
|
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().rev() {
|
||||||
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() {
|
|
||||||
// make sure we don't emit frames that are duplicates of the previous
|
// make sure we don't emit frames that are duplicates of the previous
|
||||||
if explicit_span == Some(span) {
|
if explicit_span == Some(span) {
|
||||||
last_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 {
|
} else {
|
||||||
last_span = Some(span);
|
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 block = &mir.basic_blocks()[block];
|
||||||
let source_info = if stmt < block.statements.len() {
|
let source_info = if stmt < block.statements.len() {
|
||||||
block.statements[stmt].source_info
|
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::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
|
||||||
mir::ClearCrossCrate::Clear => None,
|
mir::ClearCrossCrate::Clear => None,
|
||||||
};
|
};
|
||||||
frames.push(FrameInfo { span, location, lint_root });
|
frames.push(FrameInfo { span, instance, lint_root });
|
||||||
}
|
}
|
||||||
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
|
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
|
||||||
frames
|
frames
|
||||||
|
Loading…
x
Reference in New Issue
Block a user