From 9ec12774fd9d18cc9fdde3537def12b52c9b1ae0 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Mon, 30 Sep 2024 17:33:43 -0700 Subject: [PATCH] Check type equality when inserting a constant When the compiler inserts a constant, it will first check to see if that constant already has been created, so we aren't making millions of the same constant value - e.g. we can reuse the same integer. However, the .equals() function on all Object values was returning a false positive against Ints and Floats that have the same numeric value, i.e. Float(1.0) == Int(1). If, for example, a float 1.0 was inserted as a constant, and then an integer 1 was used as a constant later, it was erroneously retrieving the float 1.0 as an interned pointer value. This is fixed by checking if the two values' types are equal as well. Signed-off-by: Alek Ratzloff --- src/compiler.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/compiler.rs b/src/compiler.rs index 49f6eda..eeb5caf 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -513,7 +513,16 @@ impl Compiler { // simple interning - try to find a constant that is exactly equal to this one and just // return its value instead for (index, interned) in self.constants.iter().enumerate() { - if constant.borrow().equals(&*interned.borrow()) { + // check if the two objects are the same type. If they are not, this can cause an + // interesting bug where two objects that are different types are considered equal. The + // best example is a Float(1.0) and Int(1) are considered equal. + if constant + .borrow() + .ty() + .borrow() + .equals(&*interned.borrow().ty().borrow()) + && constant.borrow().equals(&*interned.borrow()) + { return Ok(index as ConstantId); } }