summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-07-04 16:54:34 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-08-29 13:24:00 +0900
commit761346a9604ca2c79777d1d67fb5dcc3c30dbf69 (patch)
treea06734056a992fdbb3ffa8c8d0ae5ce4e0a639aa /vm_insnhelper.c
parentd3e0bc07e2909f1105dcde4febb0e120eaea30b6 (diff)
Show the previous definition location,
when reopened class/module redefinition mismatched the previous definition. [Feature #11460]
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index e80a036e06..925d465669 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3389,7 +3389,7 @@ static VALUE
vm_check_if_class(ID id, rb_num_t flags, VALUE super, VALUE klass)
{
if (!RB_TYPE_P(klass, T_CLASS)) {
- rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a class", rb_id2str(id));
+ return 0;
}
else if (VM_DEFINECLASS_HAS_SUPERCLASS_P(flags)) {
VALUE tmp = rb_class_real(RCLASS_SUPER(klass));
@@ -3412,7 +3412,7 @@ static VALUE
vm_check_if_module(ID id, VALUE mod)
{
if (!RB_TYPE_P(mod, T_MODULE)) {
- rb_raise(rb_eTypeError, "%"PRIsVALUE" is not a module", rb_id2str(id));
+ return 0;
}
else {
return mod;
@@ -3442,6 +3442,22 @@ vm_declare_module(ID id, VALUE cbase)
return mod;
}
+NORETURN(static void unmatched_redefinition(const char *type, VALUE cbase, ID id, VALUE old));
+static void
+unmatched_redefinition(const char *type, VALUE cbase, ID id, VALUE old)
+{
+ VALUE name = rb_id2str(id);
+ VALUE message = rb_sprintf("%"PRIsVALUE" is not a %s",
+ name, type);
+ VALUE location = rb_const_source_location_at(cbase, id);
+ if (!NIL_P(location)) {
+ rb_str_catf(message, "\n%"PRIsVALUE":%"PRIsVALUE":"
+ " previous definition of %"PRIsVALUE" was here",
+ rb_ary_entry(location, 0), rb_ary_entry(location, 1), name);
+ }
+ rb_exc_raise(rb_exc_new_str(rb_eTypeError, message));
+}
+
static VALUE
vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
{
@@ -3458,7 +3474,9 @@ vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
/* find klass */
rb_autoload_load(cbase, id);
if ((klass = vm_const_get_under(id, flags, cbase)) != 0) {
- return vm_check_if_class(id, flags, super, klass);
+ if (!vm_check_if_class(id, flags, super, klass))
+ unmatched_redefinition("class", cbase, id, klass);
+ return klass;
}
else {
return vm_declare_class(id, flags, cbase, super);
@@ -3472,7 +3490,9 @@ vm_define_module(ID id, rb_num_t flags, VALUE cbase)
vm_check_if_namespace(cbase);
if ((mod = vm_const_get_under(id, flags, cbase)) != 0) {
- return vm_check_if_module(id, mod);
+ if (!vm_check_if_module(id, mod))
+ unmatched_redefinition("module", cbase, id, mod);
+ return mod;
}
else {
return vm_declare_module(id, cbase);