diff --git a/variable.c b/variable.c index b33725b39e..4c2048b066 100644 --- a/variable.c +++ b/variable.c @@ -68,6 +68,7 @@ struct fc_result { VALUE klass; VALUE path; VALUE track; + VALUE checked; struct fc_result *prev; }; @@ -114,20 +115,18 @@ fc_i(ID key, VALUE v, void *a) if (!RCLASS_CONST_TBL(value)) return ID_TABLE_CONTINUE; else { struct fc_result arg; - struct fc_result *list; - list = res; - while (list) { - if (list->track == value) return ID_TABLE_CONTINUE; - list = list->prev; - } + if (rb_hash_lookup2(res->checked, value, Qfalse)) + return ID_TABLE_CONTINUE; arg.name = key; arg.preferred = res->preferred; arg.path = 0; arg.klass = res->klass; arg.track = value; + arg.checked = res->checked; arg.prev = res; + rb_hash_aset(arg.checked, value, Qtrue); rb_id_table_foreach(RCLASS_CONST_TBL(value), fc_i, &arg); if (arg.path) { res->path = arg.path; @@ -155,8 +154,10 @@ find_class_path(VALUE klass, ID preferred) arg.path = 0; arg.klass = klass; arg.track = rb_cObject; + arg.checked = rb_ident_hash_new(); arg.prev = 0; if (RCLASS_CONST_TBL(rb_cObject)) { + rb_hash_aset(arg.checked, rb_cObject, Qtrue) rb_id_table_foreach(RCLASS_CONST_TBL(rb_cObject), fc_i, &arg); } if (arg.path) {