Skip to content

Commit 57a7c85

Browse files
committed
miri: backtraces with instances
1 parent 126a0e2 commit 57a7c85

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,10 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
387387
TooGeneric
388388
});
389389

390-
impl_stable_hash_for!(struct mir::interpret::FrameInfo {
390+
impl_stable_hash_for!(struct mir::interpret::FrameInfo<'tcx> {
391391
span,
392392
lint_root,
393-
location
393+
instance
394394
});
395395

396396
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });

src/librustc/mir/interpret/error.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010

1111
use std::{fmt, env};
1212

13+
use hir::map::definitions::DefPathData;
1314
use mir;
14-
use ty::{Ty, layout};
15+
use ty::{self, Ty, layout};
1516
use ty::layout::{Size, Align, LayoutError};
1617
use rustc_target::spec::abi::Abi;
1718

1819
use super::{Pointer, Scalar};
1920

2021
use backtrace::Backtrace;
2122

22-
use ty;
2323
use ty::query::TyCtxtAt;
2424
use errors::DiagnosticBuilder;
2525

@@ -52,16 +52,30 @@ pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
5252
pub struct ConstEvalErr<'tcx> {
5353
pub span: Span,
5454
pub error: ::mir::interpret::EvalErrorKind<'tcx, u64>,
55-
pub stacktrace: Vec<FrameInfo>,
55+
pub stacktrace: Vec<FrameInfo<'tcx>>,
5656
}
5757

5858
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
59-
pub struct FrameInfo {
59+
pub struct FrameInfo<'tcx> {
6060
pub span: Span,
61-
pub location: String,
61+
pub instance: ty::Instance<'tcx>,
6262
pub lint_root: Option<ast::NodeId>,
6363
}
6464

65+
impl<'tcx> fmt::Display for FrameInfo<'tcx> {
66+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67+
ty::tls::with(|tcx| {
68+
if tcx.def_key(self.instance.def_id()).disambiguated_data.data
69+
== DefPathData::ClosureExpr
70+
{
71+
write!(f, "inside call to closure")
72+
} else {
73+
write!(f, "inside call to `{}`", self.instance)
74+
}
75+
})
76+
}
77+
}
78+
6579
impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
6680
pub fn struct_error(&self,
6781
tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
@@ -135,8 +149,13 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
135149
struct_error(tcx, message)
136150
};
137151
err.span_label(self.span, self.error.to_string());
138-
for FrameInfo { span, location, .. } in &self.stacktrace {
139-
err.span_label(*span, format!("inside call to `{}`", location));
152+
// Skip the last, which is just the environment of the constant. The stacktrace
153+
// is sometimes empty because we create "fake" eval contexts in CTFE to do work
154+
// on constant values.
155+
if self.stacktrace.len() > 0 {
156+
for frame_info in &self.stacktrace[..self.stacktrace.len()-1] {
157+
err.span_label(frame_info.span, frame_info.to_string());
158+
}
140159
}
141160
Ok(err)
142161
}

src/librustc_mir/interpret/eval_context.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use std::mem;
1414
use syntax::source_map::{self, Span, DUMMY_SP};
1515
use rustc::hir::def_id::DefId;
1616
use rustc::hir::def::Def;
17-
use rustc::hir::map::definitions::DefPathData;
1817
use rustc::mir;
1918
use rustc::ty::layout::{
2019
self, Size, Align, HasDataLayout, LayoutOf, TyLayout
@@ -654,11 +653,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
654653
}
655654
}
656655

657-
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo> {
656+
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
658657
let mut last_span = None;
659658
let mut frames = Vec::new();
660-
// skip 1 because the last frame is just the environment of the constant
661-
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() {
659+
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().rev() {
662660
// make sure we don't emit frames that are duplicates of the previous
663661
if explicit_span == Some(span) {
664662
last_span = Some(span);
@@ -671,13 +669,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
671669
} else {
672670
last_span = Some(span);
673671
}
674-
let location = if self.tcx.def_key(instance.def_id()).disambiguated_data.data
675-
== DefPathData::ClosureExpr
676-
{
677-
"closure".to_owned()
678-
} else {
679-
instance.to_string()
680-
};
681672
let block = &mir.basic_blocks()[block];
682673
let source_info = if stmt < block.statements.len() {
683674
block.statements[stmt].source_info
@@ -688,7 +679,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
688679
mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
689680
mir::ClearCrossCrate::Clear => None,
690681
};
691-
frames.push(FrameInfo { span, location, lint_root });
682+
frames.push(FrameInfo { span, instance, lint_root });
692683
}
693684
trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
694685
frames

0 commit comments

Comments
 (0)