diff options
| author | bors <bors@rust-lang.org> | 2023-05-18 05:22:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-05-18 05:22:41 +0000 |
| commit | b7b026bce672f3161df83d9d503ff32c393e3768 (patch) | |
| tree | 821c6a188be8d0aabd1481efa461da4ebe2c3b46 | |
| parent | a20a08f3e2d3fb2b68e277b10d0d8413ae74d762 (diff) | |
| parent | fd034bea1a13cf557f9fa3446f8f31fa18c084f9 (diff) | |
| download | rust-b7b026bce672f3161df83d9d503ff32c393e3768.tar.gz rust-b7b026bce672f3161df83d9d503ff32c393e3768.zip | |
Auto merge of #14825 - HKalbasi:float-const-eval, r=Veykril
Fix evaluating negative for floating point types fix #14704 Unary operators was missed from #14705
| -rw-r--r-- | crates/hir-ty/src/consteval/tests.rs | 4 | ||||
| -rw-r--r-- | 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 2aac1cc057d..41e0b5188b3 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)?; |
