From fd034bea1a13cf557f9fa3446f8f31fa18c084f9 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Wed, 17 May 2023 01:27:45 +0330 Subject: [PATCH] Fix evaluating negative for floating point types --- crates/hir-ty/src/consteval/tests.rs | 4 +++ crates/hir-ty/src/mir/eval.rs | 39 ++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 12b15065ddf..aa84103dd8a 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -113,6 +113,10 @@ fn floating_point() { r#"const GOAL: f32 = 2.0 + 3.0 * 5.5 - 8.;"#, i128::from_le_bytes(pad16(&f32::to_le_bytes(10.5), true)), ); + check_number( + r#"const GOAL: f32 = -90.0 + 36.0;"#, + i128::from_le_bytes(pad16(&f32::to_le_bytes(-54.0), true)), + ); } #[test] diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 8ce16df8295..c55ecb056c0 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -759,25 +759,38 @@ impl Evaluator<'_> { let size = self.size_of_sized(&ty, locals, "operand of unary op")?; c = self.read_memory(Address::from_bytes(c)?, size)?; } - let mut c = c.to_vec(); - if ty.as_builtin() == Some(BuiltinType::Bool) { - c[0] = 1 - c[0]; + if let TyKind::Scalar(chalk_ir::Scalar::Float(f)) = ty.kind(Interner) { + match f { + chalk_ir::FloatTy::F32 => { + let c = -from_bytes!(f32, c); + Owned(c.to_le_bytes().into()) + } + chalk_ir::FloatTy::F64 => { + let c = -from_bytes!(f32, c); + Owned(c.to_le_bytes().into()) + } + } } else { - match op { - UnOp::Not => c.iter_mut().for_each(|x| *x = !*x), - UnOp::Neg => { - c.iter_mut().for_each(|x| *x = !*x); - for k in c.iter_mut() { - let o; - (*k, o) = k.overflowing_add(1); - if !o { - break; + let mut c = c.to_vec(); + if ty.as_builtin() == Some(BuiltinType::Bool) { + c[0] = 1 - c[0]; + } else { + match op { + UnOp::Not => c.iter_mut().for_each(|x| *x = !*x), + UnOp::Neg => { + c.iter_mut().for_each(|x| *x = !*x); + for k in c.iter_mut() { + let o; + (*k, o) = k.overflowing_add(1); + if !o { + break; + } } } } } + Owned(c) } - Owned(c) } Rvalue::CheckedBinaryOp(op, lhs, rhs) => { let lc = self.eval_operand(lhs, locals)?;