Include the first constant name into `Ractor::IsolationError` message
authoryui-knk <[email protected]>
Fri, 5 Jan 2024 10:45:19 +0000 (5 19:45 +0900)
committerYuichiro Kaneko <[email protected]>
Sat, 10 Feb 2024 00:23:17 +0000 (10 09:23 +0900)
If lhs of assignment is top-level constant reference, the first
constant name is omitted from error message.
This commit fixes it.

```
# shareable_constant_value: literal
::C = ["Not " + "shareable"]

# Before
# => cannot assign unshareable object to  (Ractor::IsolationError)

# After
# => cannot assign unshareable object to ::C (Ractor::IsolationError)
```

ruby_parser.c
test/ruby/test_parse.rb

index 04a49da..c48f563 100644 (file)
@@ -1060,6 +1060,7 @@ rb_node_const_decl_val(const NODE *node)
         }
         else if (n && nd_type_p(n, NODE_COLON3)) {
             // ::Const::Name
+            rb_ary_push(path, rb_id2str(RNODE_COLON3(n)->nd_mid));
             rb_ary_push(path, rb_str_new(0, 0));
         }
         else {
index 6b8c196..b6d3063 100644 (file)
@@ -1537,12 +1537,37 @@ x = __ENCODING__
   end
 
   def test_shareable_constant_value_unshareable_literal
-    assert_raise_separately(Ractor::IsolationError, /unshareable/,
+    assert_raise_separately(Ractor::IsolationError, /unshareable object to C/,
                             "#{<<~"begin;"}\n#{<<~'end;'}")
     begin;
       # shareable_constant_value: literal
       C = ["Not " + "shareable"]
     end;
+
+    assert_raise_separately(Ractor::IsolationError, /unshareable object to B::C/,
+                            "#{<<~"begin;"}\n#{<<~'end;'}")
+    begin;
+      # shareable_constant_value: literal
+      B = Class.new
+      B::C = ["Not " + "shareable"]
+    end;
+
+    assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+    begin;
+      assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::C/) do
+        # shareable_constant_value: literal
+        ::C = ["Not " + "shareable"]
+      end
+    end;
+
+    assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+    begin;
+      assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::B::C/) do
+        # shareable_constant_value: literal
+        ::B = Class.new
+        ::B::C = ["Not " + "shareable"]
+      end
+    end;
   end
 
   def test_shareable_constant_value_nonliteral