summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk1
-rw-r--r--compile.c15
-rw-r--r--complex.c12
-rw-r--r--internal/complex.h1
-rw-r--r--internal/rational.h1
-rw-r--r--rational.c13
-rw-r--r--test/ruby/test_syntax.rb15
-rw-r--r--version.h2
8 files changed, 53 insertions, 7 deletions
diff --git a/common.mk b/common.mk
index 594c165ffd..7a0068bc73 100644
--- a/common.mk
+++ b/common.mk
@@ -2803,6 +2803,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
compile.$(OBJEXT): $(top_srcdir)/internal/object.h
+compile.$(OBJEXT): $(top_srcdir)/internal/rational.h
compile.$(OBJEXT): $(top_srcdir)/internal/re.h
compile.$(OBJEXT): $(top_srcdir)/internal/serial.h
compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
diff --git a/compile.c b/compile.c
index b78c7f26d9..502d12d6c7 100644
--- a/compile.c
+++ b/compile.c
@@ -28,6 +28,7 @@
#include "internal/hash.h"
#include "internal/numeric.h"
#include "internal/object.h"
+#include "internal/rational.h"
#include "internal/re.h"
#include "internal/symbol.h"
#include "internal/thread.h"
@@ -1985,6 +1986,16 @@ cdhash_cmp(VALUE val, VALUE lit)
else if (tlit == T_FLOAT) {
return rb_float_cmp(lit, val);
}
+ else if (tlit == T_RATIONAL) {
+ const struct RRational *rat1 = RRATIONAL(val);
+ const struct RRational *rat2 = RRATIONAL(lit);
+ return cdhash_cmp(rat1->num, rat2->num) || cdhash_cmp(rat1->den, rat2->den);
+ }
+ else if (tlit == T_COMPLEX) {
+ const struct RComplex *comp1 = RCOMPLEX(val);
+ const struct RComplex *comp2 = RCOMPLEX(lit);
+ return cdhash_cmp(comp1->real, comp2->real) || cdhash_cmp(comp1->imag, comp2->imag);
+ }
else {
UNREACHABLE_RETURN(-1);
}
@@ -2003,6 +2014,10 @@ cdhash_hash(VALUE a)
return FIX2LONG(rb_big_hash(a));
case T_FLOAT:
return rb_dbl_long_hash(RFLOAT_VALUE(a));
+ case T_RATIONAL:
+ return rb_rational_hash(a);
+ case T_COMPLEX:
+ return rb_complex_hash(a);
default:
UNREACHABLE_RETURN(0);
}
diff --git a/complex.c b/complex.c
index 560d9788b2..27c1f131e3 100644
--- a/complex.c
+++ b/complex.c
@@ -1328,8 +1328,8 @@ nucomp_numerator(VALUE self)
}
/* :nodoc: */
-static VALUE
-nucomp_hash(VALUE self)
+st_index_t
+rb_complex_hash(VALUE self)
{
st_index_t v, h[2];
VALUE n;
@@ -1340,7 +1340,13 @@ nucomp_hash(VALUE self)
n = rb_hash(dat->imag);
h[1] = NUM2LONG(n);
v = rb_memhash(h, sizeof(h));
- return ST2FIX(v);
+ return v;
+}
+
+static VALUE
+nucomp_hash(VALUE self)
+{
+ return ST2FIX(rb_complex_hash(self));
}
/* :nodoc: */
diff --git a/internal/complex.h b/internal/complex.h
index 6f63a9ebeb..9eae804ddb 100644
--- a/internal/complex.h
+++ b/internal/complex.h
@@ -25,5 +25,6 @@ struct RComplex {
/* complex.c */
VALUE rb_dbl_complex_new_polar_pi(double abs, double ang);
+st_index_t rb_complex_hash(VALUE comp);
#endif /* INTERNAL_COMPLEX_H */
diff --git a/internal/rational.h b/internal/rational.h
index e53ee7b499..6bbd2a9810 100644
--- a/internal/rational.h
+++ b/internal/rational.h
@@ -33,6 +33,7 @@ VALUE rb_rational_div(VALUE self, VALUE other);
VALUE rb_lcm(VALUE x, VALUE y);
VALUE rb_rational_reciprocal(VALUE x);
VALUE rb_cstr_to_rat(const char *, int);
+VALUE rb_rational_hash(VALUE self);
VALUE rb_rational_abs(VALUE self);
VALUE rb_rational_cmp(VALUE self, VALUE other);
VALUE rb_rational_pow(VALUE self, VALUE other);
diff --git a/rational.c b/rational.c
index 872bcd7e14..d621773838 100644
--- a/rational.c
+++ b/rational.c
@@ -1744,8 +1744,8 @@ nurat_rationalize(int argc, VALUE *argv, VALUE self)
}
/* :nodoc: */
-static VALUE
-nurat_hash(VALUE self)
+st_index_t
+rb_rational_hash(VALUE self)
{
st_index_t v, h[2];
VALUE n;
@@ -1756,9 +1756,16 @@ nurat_hash(VALUE self)
n = rb_hash(dat->den);
h[1] = NUM2LONG(n);
v = rb_memhash(h, sizeof(h));
- return ST2FIX(v);
+ return v;
+}
+
+static VALUE
+nurat_hash(VALUE self)
+{
+ return ST2FIX(rb_rational_hash(self));
}
+
static VALUE
f_format(VALUE self, VALUE (*func)(VALUE))
{
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index e289eea2c2..a0cdb5b6fd 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1730,6 +1730,21 @@ eom
assert_equal [[4, 1, 5, 2, 3], {a: 1}], obj.foo(4, 5, 2, 3, a: 1){|args, kws| [args, kws]}
end
+ def test_cdhash
+ assert_separately([], <<-RUBY)
+ n = case 1 when 2r then false else true end
+ assert_equal(n, true, '[ruby-core:103759] [Bug #17854]')
+ RUBY
+ assert_separately([], <<-RUBY)
+ n = case 3/2r when 1.5r then true else false end
+ assert_equal(n, true, '[ruby-core:103759] [Bug #17854]')
+ RUBY
+ assert_separately([], <<-RUBY)
+ n = case 1i when 1i then true else false end
+ assert_equal(n, true, '[ruby-core:103759] [Bug #17854]')
+ RUBY
+ end
+
private
def not_label(x) @result = x; @not_label ||= nil end
diff --git a/version.h b/version.h
index 643f264be4..eec5108707 100644
--- a/version.h
+++ b/version.h
@@ -12,7 +12,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 2
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 81
+#define RUBY_PATCHLEVEL 82
#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 5