Skip to content

Commit

Permalink
* variable.c (rb_const_set): show the previous definition
Browse files Browse the repository at this point in the history
  location.  [EXPERIMENTAL]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33175 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nobu committed Sep 3, 2011
1 parent 3e0819c commit bc2a1f2
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 1 deletion.
5 changes: 5 additions & 0 deletions ChangeLog
@@ -1,3 +1,8 @@
Sun Sep 4 00:11:49 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>

* variable.c (rb_const_set): show the previous definition
location. [EXPERIMENTAL]

Sat Sep 3 23:56:24 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>

* configure.in (sizeof_struct_dirent_too_small): check if struct
Expand Down
2 changes: 2 additions & 0 deletions constant.h
Expand Up @@ -19,6 +19,8 @@ typedef enum {
typedef struct rb_const_entry_struct {
rb_const_flag_t flag;
VALUE value; /* should be mark */
VALUE file;
int line;
} rb_const_entry_t;

VALUE rb_mod_private_constant(int argc, VALUE *argv, VALUE obj);
Expand Down
1 change: 1 addition & 0 deletions gc.c
Expand Up @@ -1569,6 +1569,7 @@ mark_const_entry_i(ID key, const rb_const_entry_t *ce, st_data_t data)
{
struct mark_tbl_arg *arg = (void*)data;
gc_mark(arg->objspace, ce->value, arg->lev);
gc_mark(arg->objspace, ce->file, arg->lev);
return ST_CONTINUE;
}

Expand Down
1 change: 1 addition & 0 deletions internal.h
Expand Up @@ -195,6 +195,7 @@ void rb_vm_change_state(void);
void rb_vm_inc_const_missing_count(void);
void rb_thread_mark(void *th);
const void **rb_vm_get_insns_address_table(void);
VALUE rb_sourcefilename(void);

/* vm_dump.c */
void rb_vm_bugreport(void);
Expand Down
9 changes: 9 additions & 0 deletions test/ruby/test_const.rb
Expand Up @@ -45,4 +45,13 @@ def test_const
assert defined?(TEST4)
assert_equal 8, TEST4
end

def test_redefinition
c = Class.new
c.const_set(:X, 1)
assert_output(nil, <<-WARNING) {c.const_set(:X, 2)}
#{__FILE__}:#{__LINE__-1}: warning: already initialized constant X
#{__FILE__}:#{__LINE__-3}: warning: previous definition of X was here
WARNING
end
end
9 changes: 8 additions & 1 deletion variable.c
Expand Up @@ -2057,8 +2057,13 @@ rb_const_set(VALUE klass, ID id, VALUE val)
autoload_delete(klass, id);
}
else {
const char *name = rb_id2name(id);
visibility = ce->flag;
rb_warn("already initialized constant %s", rb_id2name(id));
rb_warn("already initialized constant %s", name);
if (!NIL_P(ce->file) && ce->line) {
rb_compile_warn(RSTRING_PTR(ce->file), ce->line,
"previous definition of %s was here", name);
}
}
}
}
Expand All @@ -2068,6 +2073,8 @@ rb_const_set(VALUE klass, ID id, VALUE val)
ce = ALLOC(rb_const_entry_t);
ce->flag = (rb_const_flag_t)visibility;
ce->value = val;
ce->file = rb_sourcefilename();
ce->line = rb_sourceline();

st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
}
Expand Down
14 changes: 14 additions & 0 deletions vm.c
Expand Up @@ -829,6 +829,20 @@ vm_backtrace(rb_thread_t *th, int lev)
return rb_ary_reverse(ary);
}

VALUE
rb_sourcefilename(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);

if (cfp) {
return cfp->iseq->filename;
}
else {
return Qnil;
}
}

const char *
rb_sourcefile(void)
{
Expand Down

0 comments on commit bc2a1f2

Please sign in to comment.