Skip to content

Commit

Permalink
Fix constant name of Ractor::IsolationError message
Browse files Browse the repository at this point in the history
`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)
```
  • Loading branch information
yui-knk committed Feb 10, 2024
1 parent bf72cb8 commit ea91ab6
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 12 deletions.
43 changes: 31 additions & 12 deletions ruby_parser.c
Expand Up @@ -1045,30 +1045,49 @@ 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 {
// expression::Name
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;
}
34 changes: 34 additions & 0 deletions test/ruby/test_parse.rb
Expand Up @@ -1568,6 +1568,40 @@ def test_shareable_constant_value_unshareable_literal
::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
Expand Down

0 comments on commit ea91ab6

Please sign in to comment.