Implement Integer and String eql?/equal?#1553
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for the eql? method on typed String and Integer receivers, as well as the equal? method on typed Integer receivers. The implementation handles both concrete and polymorphic arguments and includes corresponding test cases. Feedback on the changes suggests also implementing String#equal? using pointer equality, as the current implementation does not handle object identity for strings, which would incorrectly return false even when comparing a string variable to itself.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Add eql?/equal? handlers to the Integer and String arms of the typed-receiver method dispatch in emit_scalar_call, mirroring the existing Float#eql? shape. Integer#eql?/equal?(x) is value-equal only when x is itself Integer-typed (no numeric coercion, so 1.eql?(1.0) is false); equal? on a fixnum is value identity, identical to eql? here. String#eql?(x) is byte-equal only for a String-typed x, reusing sp_str_eq without coercion. A polymorphic arg checks its runtime tag; any other concrete type is never equal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Integer and String
eql?/equal?on typed receivers returned false even forequal values, because no codegen handler existed and they fell through to the
unsupported-equality path.
==already worked, andFloat#eql?was alreadyhandled — this mirrors that shape in the Integer and String arms of the
typed-receiver method dispatch (
emit_scalar_call).Integer#eql?/equal?(x): value-equal only whenxis itself Integer-typed.No numeric coercion, so
1.eql?(1.0)is false.equal?on a fixnum is valueidentity, identical to
eql?here. A Float or other concrete arg is neverequal; a polymorphic arg checks its runtime tag.
String#eql?(x): byte-equal (via the existingsp_str_eq) only whenxisString-typed, with no coercion.
String#equal?(x): object identity. Strings areconst char *whose literalsthe C compiler merges at -O2, so raw pointer equality would wrongly equate
distinct equal-valued literals (
a = "x"; b = "x"; a.equal?(b)). Instead thereflexive case is resolved syntactically:
equal?is true only when thereceiver and argument are the same side-effect-free lvalue (the same local or
instance variable read, e.g.
x.equal?(x)); every other form isconservatively false. This faithfully models
x.equal?(x)without themerged-literal false positives. The one gap is aliasing through assignment
(
a = s; a.equal?(s)), which reads as false.The general poly-receiver
eql?/equal?dispatch is left for a follow-up, asit needs the runtime value-equality helper in
lib/sp_runtime.h.New test
test/eql_equal.rb(expected regenerated from ruby) coversInteger/String
eql?/equal?, the1.eql?(1.0)false case, Stringequal?identity (same var true; distinct equal-valued and distinct literals false), and
a typed receiver with a polymorphic argument.
make testis green (1032 pass,0 fail, 0 error).
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com