From d53cf854741bbf496298c5a722988d2dd84314a1 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 27 Sep 2019 08:07:49 -0700 Subject: [PATCH] Fix warning when doing Struct.new(:x, keyword_init: true){} This is due to calling rb_mod_module_eval directly instead of using rb_funcall_passing_block. The problem with calling directly is it does not create a new VM frame, so rb_mod_module_eval was called with no arguments, but with the keyword given VM frame flag set, which causes problems internally. --- struct.c | 2 +- test/ruby/test_struct.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/struct.c b/struct.c index de40701d4e..3a631ab189 100644 --- a/struct.c +++ b/struct.c @@ -569,7 +569,7 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) setup_struct(st, rest); rb_ivar_set(st, id_keyword_init, keyword_init); if (rb_block_given_p()) { - rb_mod_module_eval(0, 0, st); + rb_funcall_passing_block(st, rb_intern("module_eval"), 0, 0); } return st; diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb index ec0a29026b..6ba28153e9 100644 --- a/test/ruby/test_struct.rb +++ b/test/ruby/test_struct.rb @@ -119,6 +119,16 @@ module TestStruct end end + def test_struct_new_with_keyword_init_and_block + struct = @Struct.new(:a, :b, keyword_init: true) do + def c + a + b + end + end + + assert_equal(3, struct.new(a: 1, b: 2).c) + end + def test_initialize klass = @Struct.new(:a) assert_raise(ArgumentError) { klass.new(1, 2) }