Address comments

上级 42d3edad
......@@ -169,6 +169,20 @@ pub fn stack(&self) -> &[Frame<'tcx>] {
&self.stack
}
/// Returns true if the current frame or any parent frame is part of a ctfe.
///
/// Used to disable features in const eval, which do not have a rfc enabling
/// them or which can't be written in a way that they produce the same output
/// that evaluating the code at runtime would produce.
pub fn const_env(&self) -> bool {
for frame in self.stack.iter().rev() {
if let StackPopCleanup::MarkStatic(_) = frame.return_to_block {
return true;
}
}
false
}
pub(crate) fn str_to_value(&mut self, s: &str) -> EvalResult<'tcx, Value> {
let ptr = self.memory.allocate_cached(s.as_bytes())?;
Ok(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::from_u128(s.len() as u128)))
......@@ -655,7 +669,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
Len(ref lvalue) => {
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc("computing the length of arrays".to_string()));
}
let src = self.eval_lvalue(lvalue)?;
......@@ -704,7 +718,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
NullaryOp(mir::NullOp::Box, ty) => {
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc("\"heap\" allocations".to_string()));
}
// FIXME: call the `exchange_malloc` lang item if available
......@@ -718,7 +732,7 @@ pub(super) fn eval_rvalue_into_lvalue(
}
NullaryOp(mir::NullOp::SizeOf, ty) => {
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc("computing the size of types (size_of)".to_string()));
}
let size = self.type_size(ty)?.expect("SizeOf nullary MIR operator called for unsized type");
......@@ -1592,12 +1606,6 @@ pub fn modify_local<F>(
}
impl<'tcx> Frame<'tcx> {
pub fn const_env(&self) -> bool {
match self.return_to_block {
StackPopCleanup::MarkStatic(_) => true,
_ => false,
}
}
pub fn get_local(&self, local: mir::Local) -> EvalResult<'tcx, Value> {
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
self.locals[local.index() - 1].ok_or(EvalError::DeadLocal)
......
......@@ -151,12 +151,8 @@ pub fn binary_op(
let usize = PrimValKind::from_uint_size(self.memory.pointer_size());
let isize = PrimValKind::from_int_size(self.memory.pointer_size());
if !left_kind.is_float() && !right_kind.is_float() {
if (!left.is_bytes() && !right.is_bytes()) && self.frame().const_env() {
if left.is_ptr() && right.is_ptr() {
return Err(EvalError::NotConst("Comparing pointers".to_string()));
} else {
return Err(EvalError::NeedsRfc("Comparing Pointers integers with pointers".to_string()));
}
if (!left.is_bytes() && !right.is_bytes()) && self.const_env() {
return Err(EvalError::NeedsRfc("Pointer arithmetic or comparison".to_string()));
}
match bin_op {
Offset if left_kind == Ptr && right_kind == usize => {
......
......@@ -37,7 +37,7 @@ pub(super) fn eval_terminator(
Goto { target } => self.goto_block(target),
SwitchInt { ref discr, ref values, ref targets, .. } => {
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc("branching (if, match, loop, ...)".to_string()));
}
let discr_val = self.eval_operand(discr)?;
......@@ -95,7 +95,7 @@ pub(super) fn eval_terminator(
Drop { ref location, target, .. } => {
trace!("TerminatorKind::drop: {:?}, {:?}", location, self.substs());
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc("invoking `Drop::drop`".to_string()));
}
let lval = self.eval_lvalue(location)?;
......@@ -430,7 +430,7 @@ fn eval_fn_call_inner(
let mir = match self.load_mir(instance.def) {
Ok(mir) => mir,
Err(EvalError::NoMirFor(path)) => {
if self.frame().const_env() {
if self.const_env() {
return Err(EvalError::NeedsRfc(format!("calling extern function `{}`", path)));
}
self.call_missing_fn(instance, destination, arg_operands, sig, path)?;
......@@ -439,7 +439,7 @@ fn eval_fn_call_inner(
Err(other) => return Err(other),
};
if self.frame().const_env() && !self.tcx.is_const_fn(instance.def_id()) {
if self.const_env() && !self.tcx.is_const_fn(instance.def_id()) {
return Err(EvalError::NotConst(format!("calling non-const fn `{}`", instance)));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册