[前][次][番号順一覧][スレッド一覧]

ruby-changes:66303

From: nagachika <ko1@a...>
Date: Sat, 22 May 2021 17:09:37 +0900 (JST)
Subject: [ruby-changes:66303] 31816356ee (ruby_3_0): merge revision(s) 2bc293e899c9d32dcd794a73de8925c49ecf8f15,d0e6c6e682b9ba2b0309a5177933a0628e8ef316,cc0dc67bbbe1951ff90004bc987f78545625d772,e1eff837cf12a8e813de9d4ff2db50c9b68b86b5,0ab0b86c8491d639b9ff1335ddf35e341ecd867e,6911b4bc82889860ff7da4ecf975504cdc3e5314: [Backport #17854]

https://git.ruby-lang.org/ruby.git/commit/?id=31816356ee

From 31816356eee6313fe968eecd4cd3ad9ac4848819 Mon Sep 17 00:00:00 2001
From: nagachika <nagachika@r...>
Date: Sat, 22 May 2021 17:09:16 +0900
Subject: merge revision(s)
 2bc293e899c9d32dcd794a73de8925c49ecf8f15,d0e6c6e682b9ba2b0309a5177933a0628e8ef316,cc0dc67bbbe1951ff90004bc987f78545625d772,e1eff837cf12a8e813de9d4ff2db50c9b68b86b5,0ab0b86c8491d639b9ff1335ddf35e341ecd867e,6911b4bc82889860ff7da4ecf975504cdc3e5314:
 [Backport #17854]

	cdhash_cmp: can take rational literals

	Rational literals are those integers suffixed with `r`.  They tend to
	be a part of more complex expressions like `123/456r`, but in theory
	they can live alone.  When such "bare" rational literals are passed to
	case-when branch, we have to take care of them.  Fixes [Bug #17854]
	---
	 common.mk                  |  1 +
	 compile.c                  |  7 +++++++
	 internal/rational.h        |  1 +
	 rational.c                 | 13 ++++++++++---
	 test/ruby/test_rational.rb |  7 +++++++
	 5 files changed, 26 insertions(+), 3 deletions(-)

	cdhash_cmp: rational literals with fractions

	Nobu kindly pointed out that rational literals can have fractions.
	---
	 compile.c                  | 5 +++--
	 test/ruby/test_rational.rb | 4 ++++
	 2 files changed, 7 insertions(+), 2 deletions(-)

	cdhash_cmp: can also take complex

	There are complex literals `123i`, which can also be a case condition.
	---
	 compile.c                  | 15 +++++++++++----
	 complex.c                  | 12 +++++++++---
	 internal/complex.h         |  1 +
	 test/ruby/test_rational.rb |  4 ++++
	 4 files changed, 25 insertions(+), 7 deletions(-)

	cdhash_cmp: recursively apply

	For instance a rational's numerator can be a bignum.  Comparison using
	C's == can be insufficient.
	---
	 compile.c | 4 ++--
	 1 file changed, 2 insertions(+), 2 deletions(-)

	cdhash_cmp: should use ||

	cf: https://github.com/ruby/ruby/pull/4469#discussion_r628386707
	---
	 compile.c | 4 ++--
	 1 file changed, 2 insertions(+), 2 deletions(-)

	test_cdhash: refactor change class

	It is now strange to test Complex in a class named Rational_Test.
	---
	 test/ruby/test_rational.rb | 15 ---------------
	 test/ruby/test_syntax.rb   | 15 +++++++++++++++
	 2 files changed, 15 insertions(+), 15 deletions(-)
---
 common.mk                |  1 +
 compile.c                | 15 +++++++++++++++
 complex.c                | 12 +++++++++---
 internal/complex.h       |  1 +
 internal/rational.h      |  1 +
 rational.c               | 13 ++++++++++---
 test/ruby/test_syntax.rb | 15 +++++++++++++++
 version.h                |  2 +-
 8 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/common.mk b/common.mk
index 594c165..7a0068b 100644
--- a/common.mk
+++ b/common.mk
@@ -2803,6 +2803,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/hash.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2803
 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 b78c7f2..502d12d 100644
--- a/compile.c
+++ b/compile.c
@@ -28,6 +28,7 @@ https://github.com/ruby/ruby/blob/trunk/compile.c#L28
 #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) https://github.com/ruby/ruby/blob/trunk/compile.c#L1986
     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) https://github.com/ruby/ruby/blob/trunk/compile.c#L2014
         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 560d978..27c1f13 100644
--- a/complex.c
+++ b/complex.c
@@ -1328,8 +1328,8 @@ nucomp_numerator(VALUE self) https://github.com/ruby/ruby/blob/trunk/complex.c#L1328
 }
 
 /* :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) https://github.com/ruby/ruby/blob/trunk/complex.c#L1340
     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 6f63a9e..9eae804 100644
--- a/internal/complex.h
+++ b/internal/complex.h
@@ -25,5 +25,6 @@ struct RComplex { https://github.com/ruby/ruby/blob/trunk/internal/complex.h#L25
 
 /* 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 e53ee7b..6bbd2a9 100644
--- a/internal/rational.h
+++ b/internal/rational.h
@@ -33,6 +33,7 @@ VALUE rb_rational_div(VALUE self, VALUE other); https://github.com/ruby/ruby/blob/trunk/internal/rational.h#L33
 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 872bcd7..d621773 100644
--- a/rational.c
+++ b/rational.c
@@ -1744,8 +1744,8 @@ nurat_rationalize(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L1744
 }
 
 /* :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) https://github.com/ruby/ruby/blob/trunk/rational.c#L1756
     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 e289eea..a0cdb5b 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1730,6 +1730,21 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L1730
     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 643f264..eec5108 100644
--- a/version.h
+++ b/version.h
@@ -12,7 +12,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L12
 # 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
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]