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 коммит произвёл Yuichiro Kaneko
Родитель bf72cb84ca
Коммит ea91ab696e
2 изменённых файлов: 65 добавлений и 12 удалений

Просмотреть файл

@ -1045,22 +1045,40 @@ VALUE
rb_node_const_decl_val(const NODE *node)
{
VALUE path;
if (RNODE_CDECL(node)->nd_vid) {
path = rb_id2str(RNODE_CDECL(node)->nd_vid);
switch (nd_type(node)) {
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();
for (; n && nd_type_p(n, NODE_COLON2); n = RNODE_COLON2(n)->nd_head) {
rb_ary_push(path, rb_id2str(RNODE_COLON2(n)->nd_mid));
path = rb_ary_new();
if (node) {
for (; node && nd_type_p(node, NODE_COLON2); node = RNODE_COLON2(node)->nd_head) {
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
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
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));
}
else {
@ -1068,7 +1086,8 @@ rb_node_const_decl_val(const NODE *node)
rb_ary_push(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;
}

Просмотреть файл

@ -1568,6 +1568,40 @@ x = __ENCODING__
::B::C = ["Not " + "shareable"]
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
def test_shareable_constant_value_nonliteral