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 <alekratz@gmail.com>
This commit is contained in:
2024-09-30 17:33:43 -07:00
parent 32b11f1d86
commit 9ec12774fd

View File

@@ -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);
}
}