Merge pull request #54 from oli-obk/clippy
Clippy and `assume` intrinsic implementation
This commit is contained in:
commit
fa2a7353b1
6 changed files with 23 additions and 7 deletions
|
@ -43,6 +43,7 @@ pub enum EvalError<'tcx> {
|
||||||
CalledClosureAsFunction,
|
CalledClosureAsFunction,
|
||||||
VtableForArgumentlessMethod,
|
VtableForArgumentlessMethod,
|
||||||
ModifiedConstantMemory,
|
ModifiedConstantMemory,
|
||||||
|
AssumptionNotHeld,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type EvalResult<'tcx, T> = Result<T, EvalError<'tcx>>;
|
pub type EvalResult<'tcx, T> = Result<T, EvalError<'tcx>>;
|
||||||
|
@ -97,6 +98,8 @@ impl<'tcx> Error for EvalError<'tcx> {
|
||||||
"tried to call a vtable function without arguments",
|
"tried to call a vtable function without arguments",
|
||||||
EvalError::ModifiedConstantMemory =>
|
EvalError::ModifiedConstantMemory =>
|
||||||
"tried to modify constant memory",
|
"tried to modify constant memory",
|
||||||
|
EvalError::AssumptionNotHeld =>
|
||||||
|
"`assume` argument was false"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
let mir = self.mir();
|
let mir = self.mir();
|
||||||
let basic_block = &mir.basic_blocks()[block];
|
let basic_block = &mir.basic_blocks()[block];
|
||||||
|
|
||||||
if let Some(ref stmt) = basic_block.statements.get(stmt_id) {
|
if let Some(stmt) = basic_block.statements.get(stmt_id) {
|
||||||
let mut new = Ok(0);
|
let mut new = Ok(0);
|
||||||
ConstantExtractor {
|
ConstantExtractor {
|
||||||
span: stmt.source_info.span,
|
span: stmt.source_info.span,
|
||||||
|
|
|
@ -284,8 +284,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
"sub_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Sub, &args[0], &args[1], dest, dest_layout)?,
|
"sub_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Sub, &args[0], &args[1], dest, dest_layout)?,
|
||||||
"mul_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Mul, &args[0], &args[1], dest, dest_layout)?,
|
"mul_with_overflow" => self.intrinsic_with_overflow(mir::BinOp::Mul, &args[0], &args[1], dest, dest_layout)?,
|
||||||
|
|
||||||
// FIXME: turn into an assertion to catch wrong `assume` that would cause UB in llvm
|
"assume" => {
|
||||||
"assume" => {}
|
if !self.memory.read_bool(args_ptrs[0])? {
|
||||||
|
return Err(EvalError::AssumptionNotHeld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"copy_nonoverlapping" => {
|
"copy_nonoverlapping" => {
|
||||||
let elem_ty = substs.type_at(0);
|
let elem_ty = substs.type_at(0);
|
||||||
|
|
|
@ -20,8 +20,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
|
|
||||||
debug!("get_vtable(trait_ref={:?})", trait_ref);
|
debug!("get_vtable(trait_ref={:?})", trait_ref);
|
||||||
|
|
||||||
let methods: Vec<_> = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
|
let methods: Vec<_> = traits::supertraits(tcx, trait_ref).flat_map(|trait_ref| {
|
||||||
match self.fulfill_obligation(trait_ref.clone()) {
|
match self.fulfill_obligation(trait_ref) {
|
||||||
// Should default trait error here?
|
// Should default trait error here?
|
||||||
traits::VtableDefaultImpl(_) |
|
traits::VtableDefaultImpl(_) |
|
||||||
traits::VtableBuiltin(_) => {
|
traits::VtableBuiltin(_) => {
|
||||||
|
@ -164,7 +164,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
// method could then never be called, so we do not want to
|
// method could then never be called, so we do not want to
|
||||||
// try and trans it, in that case. Issue #23435.
|
// try and trans it, in that case. Issue #23435.
|
||||||
if mth.is_provided {
|
if mth.is_provided {
|
||||||
let predicates = mth.method.predicates.predicates.subst(self.tcx, &mth.substs);
|
let predicates = mth.method.predicates.predicates.subst(self.tcx, mth.substs);
|
||||||
if !self.normalize_and_test_predicates(predicates) {
|
if !self.normalize_and_test_predicates(predicates) {
|
||||||
debug!("get_vtable_methods: predicates do not hold");
|
debug!("get_vtable_methods: predicates do not hold");
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -314,7 +314,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||||
Some(&FunctionDefinition {
|
Some(&FunctionDefinition {
|
||||||
def_id,
|
def_id,
|
||||||
kind: FunctionKind::Closure { ref substs, ref ty }
|
kind: FunctionKind::Closure { ref substs, ref ty }
|
||||||
}) => Ok((def_id, substs.clone(), ty.clone())),
|
}) => Ok((def_id, *substs, ty.clone())),
|
||||||
Some(&FunctionDefinition {
|
Some(&FunctionDefinition {
|
||||||
kind: FunctionKind::Function { .. }, ..
|
kind: FunctionKind::Function { .. }, ..
|
||||||
}) => Err(EvalError::CalledClosureAsFunction),
|
}) => Err(EvalError::CalledClosureAsFunction),
|
||||||
|
|
10
tests/compile-fail/assume.rs
Normal file
10
tests/compile-fail/assume.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 5;
|
||||||
|
unsafe {
|
||||||
|
std::intrinsics::assume(x < 10);
|
||||||
|
std::intrinsics::assume(x > 1);
|
||||||
|
std::intrinsics::assume(x > 42); //~ ERROR: `assume` argument was false
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue