diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 6c16c4f2219..36f17688e8e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -164,6 +164,20 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { } } +impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> { + /// Return the `SourceInfo` of the current instruction. + pub fn current_source_info(&self) -> Option { + self.block.map(|block| { + let block = &self.body.basic_blocks()[block]; + if self.stmt < block.statements.len() { + block.statements[self.stmt].source_info + } else { + block.terminator().source_info + } + }) + } +} + impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &layout::TargetDataLayout { @@ -828,34 +842,28 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn generate_stacktrace(&self, explicit_span: Option) -> Vec> { let mut last_span = None; let mut frames = Vec::new(); - for &Frame { instance, span, body, block, stmt, .. } in self.stack().iter().rev() { + for frame 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); + if explicit_span == Some(frame.span) { + last_span = Some(frame.span); continue; } if let Some(last) = last_span { - if last == span { + if last == frame.span { continue; } } else { - last_span = Some(span); + last_span = Some(frame.span); } - let lint_root = block.and_then(|block| { - let block = &body.basic_blocks()[block]; - let source_info = if stmt < block.statements.len() { - block.statements[stmt].source_info - } else { - block.terminator().source_info - }; - match &body.source_scopes[source_info.scope].local_data { + let lint_root = frame.current_source_info().and_then(|source_info| { + match &frame.body.source_scopes[source_info.scope].local_data { mir::ClearCrossCrate::Set(data) => Some(data.lint_root), mir::ClearCrossCrate::Clear => None, } }); - frames.push(FrameInfo { call_site: span, instance, lint_root }); + frames.push(FrameInfo { call_site: frame.span, instance: frame.instance, lint_root }); } trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); frames