Fix constant name of Ractor::IsolationError message

`dest` of `const_decl_path` is `NODE_COLON2` or `NODE_COLON3` in some cases.
For example, `B::C ||= [“Not ” + “shareable”]` passes `NODE_COLON2`
and `::C ||= [“Not ” + “shareable”]` passes `NODE_COLON3`.
This commit fixes `Ractor::IsolationError` message for such case.

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

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

# After
# => cannot assign unshareable object to ::C (Ractor::IsolationError)
```
This commit is contained in:
yui-knk 2024-01-06 17:33:20 +09:00 committed by Yuichiro Kaneko
parent bf72cb84ca
commit ea91ab696e
2 changed files with 65 additions and 12 deletions

View File

@ -1045,22 +1045,40 @@ VALUE
rb_node_const_decl_val(const NODE *node) rb_node_const_decl_val(const NODE *node)
{ {
VALUE path; VALUE path;
if (RNODE_CDECL(node)->nd_vid) { switch (nd_type(node)) {
path = rb_id2str(RNODE_CDECL(node)->nd_vid); case NODE_CDECL:
if (RNODE_CDECL(node)->nd_vid) {
path = rb_id2str(RNODE_CDECL(node)->nd_vid);
goto end;
}
else {
node = RNODE_CDECL(node)->nd_else;
}
break;
case NODE_COLON2:
break;
case NODE_COLON3:
// ::Const
path = rb_str_new_cstr("::");
rb_str_append(path, rb_id2str(RNODE_COLON3(node)->nd_mid));
goto end;
default:
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
UNREACHABLE_RETURN(0);
} }
else {
NODE *n = RNODE_CDECL(node)->nd_else; path = rb_ary_new();
path = rb_ary_new(); if (node) {
for (; n && nd_type_p(n, NODE_COLON2); n = RNODE_COLON2(n)->nd_head) { for (; node && nd_type_p(node, NODE_COLON2); node = RNODE_COLON2(node)->nd_head) {
rb_ary_push(path, rb_id2str(RNODE_COLON2(n)->nd_mid)); rb_ary_push(path, rb_id2str(RNODE_COLON2(node)->nd_mid));
} }
if (n && nd_type_p(n, NODE_CONST)) { if (node && nd_type_p(node, NODE_CONST)) {
// Const::Name // Const::Name
rb_ary_push(path, rb_id2str(RNODE_CONST(n)->nd_vid)); rb_ary_push(path, rb_id2str(RNODE_CONST(node)->nd_vid));
} }
else if (n && nd_type_p(n, NODE_COLON3)) { else if (node && nd_type_p(node, NODE_COLON3)) {
// ::Const::Name // ::Const::Name
rb_ary_push(path, rb_id2str(RNODE_COLON3(n)->nd_mid)); rb_ary_push(path, rb_id2str(RNODE_COLON3(node)->nd_mid));
rb_ary_push(path, rb_str_new(0, 0)); rb_ary_push(path, rb_str_new(0, 0));
} }
else { else {
@ -1068,7 +1086,8 @@ rb_node_const_decl_val(const NODE *node)
rb_ary_push(path, rb_str_new_cstr("...")); rb_ary_push(path, rb_str_new_cstr("..."));
} }
path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::")); path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::"));
path = rb_fstring(path);
} }
end:
path = rb_fstring(path);
return path; return path;
} }

View File

@ -1568,6 +1568,40 @@ x = __ENCODING__
::B::C = ["Not " + "shareable"] ::B::C = ["Not " + "shareable"]
end end
end; 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_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 ::B::C/) do
# shareable_constant_value: literal
::B = Class.new
::B::C ||= ["Not " + "shareable"]
end
end;
assert_raise_separately(Ractor::IsolationError, /unshareable object to ...::C/,
"#{<<~"begin;"}\n#{<<~'end;'}")
begin;
# shareable_constant_value: literal
B = Class.new
def self.expr; B; end
expr::C ||= ["Not " + "shareable"]
end;
end end
def test_shareable_constant_value_nonliteral def test_shareable_constant_value_nonliteral