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

ruby-changes:72122

From: Noah <ko1@a...>
Date: Sat, 11 Jun 2022 02:53:00 +0900 (JST)
Subject: [ruby-changes:72122] 9ed9cc9852 (master): Add tests for a variety of string-subclass operations (#5999)

https://git.ruby-lang.org/ruby.git/commit/?id=9ed9cc9852

From 9ed9cc9852a7cf12c71114c3c65b239c7af1518b Mon Sep 17 00:00:00 2001
From: Noah Gibbs <noah.gibbs@s...>
Date: Fri, 10 Jun 2022 18:52:43 +0100
Subject: Add tests for a variety of string-subclass operations (#5999)

This way YJIT has to match CRuby for each of them.
Remove unused string_p() Rust function
---
 bootstraptest/test_yjit.rb | 79 ++++++++++++++++++++++++++++++++++++++++++++--
 yjit/src/cruby.rs          |  5 ---
 2 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 3ae0cdb33a..09bce6735b 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1354,7 +1354,7 @@ assert_equal 'meh', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1354
   inval_method
 }
 
-# test that overriding to_s on a String subclass isn't over-optimised
+# test that overriding to_s on a String subclass works consistently
 assert_equal 'meh', %q{
   class MyString < String
     def to_s
@@ -1368,7 +1368,7 @@ assert_equal 'meh', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1368
 
   OBJ = MyString.new
 
-  # Should return 'meh' both times
+  # Should return '' both times
   test_to_s("")
   test_to_s("")
 
@@ -1421,6 +1421,81 @@ assert_equal 'false', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1421
   uplus_str.frozen?
 }
 
+# String-subclass objects should behave as expected inside string-interpolation via concatstrings
+assert_equal 'monkeys, yo!', %q{
+  class MyString < String
+    # This is a terrible idea in production code, but we'd like YJIT to match CRuby
+    def to_s
+      super + ", yo!"
+    end
+  end
+
+  m = MyString.new('monkeys')
+  "#{m.to_s}"
+
+  raise "String-subclass to_s should not be called for interpolation" if "#{m}" != 'monkeys'
+  raise "String-subclass to_s should be called explicitly during interpolation" if "#{m.to_s}" != 'monkeys, yo!'
+
+  m.to_s
+}
+
+# String-subclass objects should behave as expected for string equality
+assert_equal 'a', %q{
+  class MyString < String
+    # This is a terrible idea in production code, but we'd like YJIT to match CRuby
+    def ==(b)
+      "#{self}_" == b
+    end
+  end
+
+  ma = MyString.new("a")
+
+  raise "Not dispatching to string-subclass equality!" if ma == "a" || ma != "a_"
+  raise "Incorrectly dispatching for String equality!" if "a_" == ma || "a" != ma
+  raise "Error in equality between string subclasses!" if ma != MyString.new("a_")
+  # opt_equality has an explicit "string always equals itself" test, but should never be used when == is redefined
+  raise "Error in reflexive equality!" if ma == ma
+
+  ma.to_s
+}
+
+assert_equal '', %q{
+  class MyString < String; end
+
+  a = "a"
+  ma = MyString.new("a")
+  fma = MyString.new("a").freeze
+
+  # Test to_s on string subclass
+  raise "to_s should not duplicate a String!" if a.object_id != a.to_s.object_id
+  raise "to_s should duplicate a String subclass!" if ma.object_id == ma.to_s.object_id
+
+  # Test freeze, uminus and uplus on string subclass
+  raise "Freezing a string subclass should not duplicate it!" if fma.object_id != fma.freeze.object_id
+  raise "Unary minus on frozen string subclass should not duplicate it!" if fma.object_id != (-fma).object_id
+  raise "Unary minus on unfrozen string subclass should duplicate it!" if ma.object_id == (-ma).object_id
+  raise "Unary plus on unfrozen string subclass should not duplicate it!" if ma.object_id != (+ma).object_id
+  raise "Unary plus on frozen string subclass should duplicate it!" if fma.object_id == (+fma).object_id
+
+  ''
+}
+
+# Test << operator on string subclass
+assert_equal 'abab', %q{
+  class MyString < String; end
+
+  a = -"a"
+  mb = MyString.new("b")
+
+  buf = String.new
+  mbuf = MyString.new
+
+  buf << a << mb
+  mbuf << a << mb
+
+  buf + mbuf
+}
+
 # test invokebuiltin as used in struct assignment
 assert_equal '123', %q{
   def foo(obj)
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index 3a172391f6..da9a84a160 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -461,11 +461,6 @@ impl VALUE { https://github.com/ruby/ruby/blob/trunk/yjit/src/cruby.rs#L461
         self == Qnil
     }
 
-    /// Returns true or false depending whether the value is a string
-    pub fn string_p(self) -> bool {
-        unsafe { CLASS_OF(self) == rb_cString }
-    }
-
     /// Read the flags bits from the RBasic object, then return a Ruby type enum (e.g. RUBY_T_ARRAY)
     pub fn builtin_type(self) -> ruby_value_type {
         assert!(!self.special_const_p());
-- 
cgit v1.2.1


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

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