allow unary operations and ignore StorageLive/Dead stmts
This commit is contained in:
parent
5a277822a5
commit
d1294e0ce2
@ -174,6 +174,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// We do not allow all binary operations in abstract consts, so filter disallowed ones.
|
||||||
fn check_binop(op: mir::BinOp) -> bool {
|
fn check_binop(op: mir::BinOp) -> bool {
|
||||||
use mir::BinOp::*;
|
use mir::BinOp::*;
|
||||||
match op {
|
match op {
|
||||||
@ -183,6 +184,15 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// While we currently allow all unary operations, we still want to explicitly guard against
|
||||||
|
/// future changes here.
|
||||||
|
fn check_unop(op: mir::UnOp) -> bool {
|
||||||
|
use mir::UnOp::*;
|
||||||
|
match op {
|
||||||
|
Not | Neg => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_statement(&mut self, stmt: &mir::Statement<'tcx>) -> Option<()> {
|
fn build_statement(&mut self, stmt: &mir::Statement<'tcx>) -> Option<()> {
|
||||||
debug!("AbstractConstBuilder: stmt={:?}", stmt);
|
debug!("AbstractConstBuilder: stmt={:?}", stmt);
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
@ -191,6 +201,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||||||
match *rvalue {
|
match *rvalue {
|
||||||
Rvalue::Use(ref operand) => {
|
Rvalue::Use(ref operand) => {
|
||||||
self.locals[local] = self.operand_to_node(operand)?;
|
self.locals[local] = self.operand_to_node(operand)?;
|
||||||
|
Some(())
|
||||||
}
|
}
|
||||||
Rvalue::BinaryOp(op, ref lhs, ref rhs) if Self::check_binop(op) => {
|
Rvalue::BinaryOp(op, ref lhs, ref rhs) if Self::check_binop(op) => {
|
||||||
let lhs = self.operand_to_node(lhs)?;
|
let lhs = self.operand_to_node(lhs)?;
|
||||||
@ -198,6 +209,8 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||||||
self.locals[local] = self.nodes.push(Node::Binop(op, lhs, rhs));
|
self.locals[local] = self.nodes.push(Node::Binop(op, lhs, rhs));
|
||||||
if op.is_checkable() {
|
if op.is_checkable() {
|
||||||
bug!("unexpected unchecked checkable binary operation");
|
bug!("unexpected unchecked checkable binary operation");
|
||||||
|
} else {
|
||||||
|
Some(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) if Self::check_binop(op) => {
|
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) if Self::check_binop(op) => {
|
||||||
@ -205,14 +218,20 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||||||
let rhs = self.operand_to_node(rhs)?;
|
let rhs = self.operand_to_node(rhs)?;
|
||||||
self.locals[local] = self.nodes.push(Node::Binop(op, lhs, rhs));
|
self.locals[local] = self.nodes.push(Node::Binop(op, lhs, rhs));
|
||||||
self.checked_op_locals.insert(local);
|
self.checked_op_locals.insert(local);
|
||||||
|
Some(())
|
||||||
}
|
}
|
||||||
_ => return None,
|
Rvalue::UnaryOp(op, ref operand) if Self::check_unop(op) => {
|
||||||
|
let operand = self.operand_to_node(operand)?;
|
||||||
|
self.locals[local] = self.nodes.push(Node::UnaryOp(op, operand));
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return None,
|
// These are not actually relevant for us here, so we can ignore them.
|
||||||
|
StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Some(()),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_terminator(
|
fn build_terminator(
|
||||||
|
14
src/test/ui/const-generics/const_evaluatable_checked/unop.rs
Normal file
14
src/test/ui/const-generics/const_evaluatable_checked/unop.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// run-pass
|
||||||
|
#![feature(const_generics, const_evaluatable_checked)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct Foo<const B: bool>;
|
||||||
|
|
||||||
|
fn test<const N: usize>() -> Foo<{ !(N > 10) }> where Foo<{ !(N > 10) }>: Sized {
|
||||||
|
Foo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: Foo<false> = test::<12>();
|
||||||
|
let _: Foo<true> = test::<9>();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user