Simplify the return lvalue

This commit is contained in:
Oliver Schneider 2017-06-19 13:29:04 +02:00
parent a2baeb516c
commit 75fddee700
No known key found for this signature in database
GPG Key ID: A69F8D225B3AD7D9
5 changed files with 19 additions and 12 deletions

View File

@ -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<Lvalue<'tcx>>,
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<Value>`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<Lvalue<'tcx>>,
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 {

View File

@ -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_) => {

View File

@ -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),
)
});

View File

@ -49,7 +49,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
instance,
span,
mir,
Some(Lvalue::zst()),
Lvalue::zst(),
StackPopCleanup::None,
)?;

View File

@ -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),
)?;