Skip to content

Commit

Permalink
Any.== checks for Meta.is_same_object (#6065)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akirathan committed Apr 17, 2023
1 parent c5b5696 commit 3507484
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,43 +214,38 @@ boolean equalsStrings(Object selfString, Object otherString,
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
return Normalizer.compare(
selfJavaString,
otherJavaString,
Normalizer.FOLD_CASE_DEFAULT
) == 0;
return Normalizer.compare(selfJavaString, otherJavaString, Normalizer.FOLD_CASE_DEFAULT) == 0;
}

@Specialization(
guards = "isPrimitive(self, strings) != isPrimitive(other, strings)"
)
boolean equalsDifferent(Object self, Object other, @CachedLibrary(limit = "10") InteropLibrary strings) {
@Specialization(guards = "isPrimitive(self, interop) != isPrimitive(other, interop)")
boolean equalsDifferent(
Object self, Object other, @CachedLibrary(limit = "10") InteropLibrary interop) {
return false;
}

/** Equals for Atoms and AtomConstructors */

@Specialization
boolean equalsAtomConstructors(AtomConstructor self, AtomConstructor other) {
return self == other;
}

@Specialization
boolean equalsAtoms(Atom self, Atom other, @Cached EqualsAtomNode equalsNode) {
return equalsNode.execute(self, other);
return self == other || equalsNode.execute(self, other);
}
@Specialization(guards = "isNotPrimitive(self, other, strings, warnings)")

@Specialization(guards = "isNotPrimitive(self, other, interop, warnings)")
boolean equalsComplex(
Object self, Object other,
@Cached EqualsComplexNode complex,
@CachedLibrary(limit = "10") InteropLibrary strings,
@CachedLibrary(limit = "10") WarningsLibrary warnings
) {
return complex.execute(self, other);
Object self,
Object other,
@Cached EqualsComplexNode equalsComplex,
@CachedLibrary(limit = "10") InteropLibrary interop,
@CachedLibrary(limit = "10") WarningsLibrary warnings) {
return self == other || equalsComplex.execute(self, other);
}

static boolean isNotPrimitive(Object a, Object b, InteropLibrary strings, WarningsLibrary warnings) {
static boolean isNotPrimitive(
Object a, Object b, InteropLibrary interop, WarningsLibrary warnings) {
if (a instanceof AtomConstructor && b instanceof AtomConstructor) {
return false;
}
Expand All @@ -260,22 +255,22 @@ static boolean isNotPrimitive(Object a, Object b, InteropLibrary strings, Warnin
if (warnings.hasWarnings(a) || warnings.hasWarnings(b)) {
return true;
}
return !isPrimitive(a, strings) && !isPrimitive(b, strings);
return !isPrimitive(a, interop) && !isPrimitive(b, interop);
}

/**
* Return true iff object is a primitive value used in some specializations
* guard. By primitive value we mean any value that can be present in Enso, so,
* for example, not Integer, as that cannot be present in Enso.
* All the primitive types should be handled in their corresponding specializations.
* See {@link org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode}.
* Return true iff object is a primitive value used in some specializations guard. By primitive
* value we mean any value that can be present in Enso, so, for example, not Integer, as that
* cannot be present in Enso. All the primitive types should be handled in their corresponding
* specializations. See {@link
* org.enso.interpreter.node.expression.builtin.interop.syntax.HostValueToEnsoNode}.
*/
static boolean isPrimitive(Object object, InteropLibrary strings) {
return object instanceof Boolean ||
object instanceof Long ||
object instanceof Double ||
object instanceof EnsoBigInteger ||
object instanceof Text ||
strings.isString(object);
static boolean isPrimitive(Object object, InteropLibrary interop) {
return object instanceof Boolean
|| object instanceof Long
|| object instanceof Double
|| object instanceof EnsoBigInteger
|| object instanceof Text
|| interop.isString(object);
}
}
18 changes: 18 additions & 0 deletions test/Tests/src/Semantic/Equals_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ type Child_Comparator

Comparable.from (_:Child) = Child_Comparator

## Type that violates reflexivity
type My_Nan
Value val

type My_Nan_Comparator
compare _ _ = Nothing
hash _ = 0

Comparable.from (_:My_Nan) = My_Nan_Comparator

type Parent
Value child

Expand Down Expand Up @@ -159,6 +169,14 @@ spec =
four_field = FourFieldType.Value 1 2 3 4
(rect == four_field).should_be_false

Test.specify "Any.== should check for Meta.is_same_object" <|
obj_1 = My_Nan.Value 42
obj_2 = My_Nan.Value 42
obj_1 == obj_2 . should_be_false
Meta.is_same_object obj_1 obj_2 . should_be_false
obj_1 == obj_1 . should_be_true
Meta.is_same_object obj_1 obj_1 . should_be_true

Test.specify "should handle `==` on types" <|
(Child == Child).should_be_true
(Child == Point).should_be_false
Expand Down

0 comments on commit 3507484

Please sign in to comment.