From 75fddee700c67ccef35e9496451fbe15e29084d8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 19 Jun 2017 13:29:04 +0200 Subject: [PATCH] Simplify the return lvalue --- src/eval_context.rs | 7 +++---- src/lvalue.rs | 10 +++++++++- src/step.rs | 4 ++-- src/terminator/drop.rs | 2 +- src/terminator/mod.rs | 8 ++++---- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/eval_context.rs b/src/eval_context.rs index 69469c30e48..185f4e1709b 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -66,8 +66,7 @@ pub struct Frame<'tcx> { pub return_to_block: StackPopCleanup, /// The location where the result of the current stack frame should be written to. - /// None if the function is a diverging function - pub return_lvalue: Option>, + pub return_lvalue: Lvalue<'tcx>, /// The list of locals for this stack frame, stored in order as /// `[arguments..., variables..., temporaries...]`. The locals are stored as `Option`s. @@ -272,7 +271,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { instance: ty::Instance<'tcx>, span: codemap::Span, mir: &'tcx mir::Mir<'tcx>, - return_lvalue: Option>, + return_lvalue: Lvalue<'tcx>, return_to_block: StackPopCleanup, ) -> EvalResult<'tcx> { ::log_settings::settings().indentation += 1; @@ -329,7 +328,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { ::log_settings::settings().indentation -= 1; let frame = self.stack.pop().expect("tried to pop a stack frame, but there were none"); match frame.return_to_block { - StackPopCleanup::MarkStatic(mutable) => if let Lvalue::Global(id) = frame.return_lvalue.expect("diverging static") { + StackPopCleanup::MarkStatic(mutable) => if let Lvalue::Global(id) = frame.return_lvalue { let global_value = self.globals.get_mut(&id) .expect("global should have been cached (static)"); match global_value.value { diff --git a/src/lvalue.rs b/src/lvalue.rs index b61c18274ae..0205472254c 100644 --- a/src/lvalue.rs +++ b/src/lvalue.rs @@ -64,6 +64,14 @@ pub struct Global<'tcx> { } impl<'tcx> Lvalue<'tcx> { + /// Produces an Lvalue that will error if attempted to be read from + pub fn undef() -> Self { + Lvalue::Ptr { + ptr: PrimVal::Undef, + extra: LvalueExtra::None, + } + } + pub fn zst() -> Self { Self::from_ptr(Pointer::zst_ptr()) } @@ -148,7 +156,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { pub(super) fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'tcx>> { use rustc::mir::Lvalue::*; let lvalue = match *mir_lvalue { - Local(mir::RETURN_POINTER) => self.frame().return_lvalue.expect("diverging function returned"), + Local(mir::RETURN_POINTER) => self.frame().return_lvalue, Local(local) => Lvalue::Local { frame: self.stack.len() - 1, local, field: None }, Static(ref static_) => { diff --git a/src/step.rs b/src/step.rs index a1a9409e2e6..48b9fecd3d3 100644 --- a/src/step.rs +++ b/src/step.rs @@ -192,7 +192,7 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> { instance, span, mir, - Some(Lvalue::Global(cid)), + Lvalue::Global(cid), cleanup, ) }); @@ -235,7 +235,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> { this.ecx.push_stack_frame(this.instance, constant.span, mir, - Some(Lvalue::Global(cid)), + Lvalue::Global(cid), StackPopCleanup::MarkStatic(false), ) }); diff --git a/src/terminator/drop.rs b/src/terminator/drop.rs index 463d9b3388b..663d05254e5 100644 --- a/src/terminator/drop.rs +++ b/src/terminator/drop.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { instance, span, mir, - Some(Lvalue::zst()), + Lvalue::zst(), StackPopCleanup::None, )?; diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index b9182a532e4..6ec607295dc 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -30,7 +30,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { use rustc::mir::TerminatorKind::*; match terminator.kind { Return => { - self.dump_local(self.frame().return_lvalue.expect("diverging function returned")); + self.dump_local(self.frame().return_lvalue); self.pop_stack_frame()? } @@ -430,8 +430,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { Err(other) => return Err(other), }; let (return_lvalue, return_to_block) = match destination { - Some((lvalue, block)) => (Some(lvalue), StackPopCleanup::Goto(block)), - None => (None, StackPopCleanup::None), + Some((lvalue, block)) => (lvalue, StackPopCleanup::Goto(block)), + None => (Lvalue::undef(), StackPopCleanup::None), }; self.push_stack_frame( @@ -606,7 +606,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { f_instance, mir.span, mir, - Some(Lvalue::zst()), + Lvalue::zst(), StackPopCleanup::Goto(dest_block), )?;