diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-02-15 16:29:10 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-02-15 16:29:10 +0000 |
commit | e68cf6f561560b624ea7a74eda0bd9d58f7020b1 (patch) | |
tree | b180422d43c56733bf0f2c35c677864577f52753 | |
parent | 257ec8c9afd3cfc6e191a582d42390ce83f53c1e (diff) |
merge revision(s) r44758,r44759,r44760: [Backport #9466]
object.c: error message encoding
* object.c (convert_type, rb_convert_type, rb_check_convert_type),
(rb_to_integer): preserve class name encoding error messages.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@44987 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | object.c | 39 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 19 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm_eval.c | 33 |
4 files changed, 59 insertions, 34 deletions
@@ -2350,13 +2350,16 @@ convert_type(VALUE val, const char *tname, const char *method, int raise) r = rb_check_funcall(val, m, 0, 0); if (r == Qundef) { if (raise) { - rb_raise(rb_eTypeError, i < IMPLICIT_CONVERSIONS - ? "no implicit conversion of %s into %s" - : "can't convert %s into %s", - NIL_P(val) ? "nil" : - val == Qtrue ? "true" : - val == Qfalse ? "false" : - rb_obj_classname(val), + const char *msg = i < IMPLICIT_CONVERSIONS ? + "no implicit conversion of" : "can't convert"; + const char *cname = NIL_P(val) ? "nil" : + val == Qtrue ? "true" : + val == Qfalse ? "false" : + NULL; + if (cname) + rb_raise(rb_eTypeError, "%s %s into %s", msg, cname, tname); + rb_raise(rb_eTypeError, "%s %"PRIsVALUE" into %s", msg, + rb_obj_class(val), tname); } return Qnil; @@ -2364,6 +2367,16 @@ convert_type(VALUE val, const char *tname, const char *method, int raise) return r; } +NORETURN(static void conversion_mismatch(VALUE, const char *, const char *, VALUE)); +static void +conversion_mismatch(VALUE val, const char *tname, const char *method, VALUE result) +{ + VALUE cname = rb_obj_class(val); + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")", + cname, tname, cname, method, rb_obj_class(result)); +} + VALUE rb_convert_type(VALUE val, int type, const char *tname, const char *method) { @@ -2372,9 +2385,7 @@ rb_convert_type(VALUE val, int type, const char *tname, const char *method) if (TYPE(val) == type) return val; v = convert_type(val, tname, method, TRUE); if (TYPE(v) != type) { - const char *cname = rb_obj_classname(val); - rb_raise(rb_eTypeError, "can't convert %s to %s (%s#%s gives %s)", - cname, tname, cname, method, rb_obj_classname(v)); + conversion_mismatch(val, tname, method, v); } return v; } @@ -2389,9 +2400,7 @@ rb_check_convert_type(VALUE val, int type, const char *tname, const char *method v = convert_type(val, tname, method, FALSE); if (NIL_P(v)) return Qnil; if (TYPE(v) != type) { - const char *cname = rb_obj_classname(val); - rb_raise(rb_eTypeError, "can't convert %s to %s (%s#%s gives %s)", - cname, tname, cname, method, rb_obj_classname(v)); + conversion_mismatch(val, tname, method, v); } return v; } @@ -2406,9 +2415,7 @@ rb_to_integer(VALUE val, const char *method) if (RB_TYPE_P(val, T_BIGNUM)) return val; v = convert_type(val, "Integer", method, TRUE); if (!rb_obj_is_kind_of(v, rb_cInteger)) { - const char *cname = rb_obj_classname(val); - rb_raise(rb_eTypeError, "can't convert %s to Integer (%s#%s gives %s)", - cname, cname, method, rb_obj_classname(v)); + conversion_mismatch(val, "Integer", method, v); } return v; } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 18b0d6f725..107d80b1a4 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -224,6 +224,25 @@ class TestException < Test::Unit::TestCase assert_raise(ArgumentError) { raise 1, 1, 1, 1 } end + def test_type_error_message_encoding + c = eval("Module.new do break class C\u{4032}; self; end; end") + o = c.new + e = assert_raise(TypeError) do + ""[o] + end + assert_match(/C\u{4032}/, e.message) + c.class_eval {def to_int; self; end} + e = assert_raise(TypeError) do + ""[o] + end + assert_match(/C\u{4032}/, e.message) + c.class_eval {def to_a; self; end} + assert_raise(TypeError) do + [*o] + end + assert_match(/C\u{4032}/, e.message) + end + def test_errat assert_in_out_err([], "p $@", %w(nil), []) @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.0.0" #define RUBY_RELEASE_DATE "2014-02-16" -#define RUBY_PATCHLEVEL 421 +#define RUBY_PATCHLEVEL 422 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 2 @@ -486,38 +486,37 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr) VALUE klass = CLASS_OF(recv); if (!klass) { - VALUE flags, klass; - if (IMMEDIATE_P(recv)) { + VALUE flags; + if (SPECIAL_CONST_P(recv)) { rb_raise(rb_eNotImpError, - "method `%s' called on unexpected immediate object (%p)", - rb_id2name(mid), (void *)recv); + "method `%"PRIsVALUE"' called on unexpected immediate object (%p)", + rb_id2str(mid), (void *)recv); } flags = RBASIC(recv)->flags; - klass = RBASIC(recv)->klass; if (flags == 0) { rb_raise(rb_eNotImpError, - "method `%s' called on terminated object" - " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")", - rb_id2name(mid), (void *)recv, flags, klass); + "method `%"PRIsVALUE"' called on terminated object" + " (%p flags=0x%"PRIxVALUE")", + rb_id2str(mid), (void *)recv, flags); } else { int type = BUILTIN_TYPE(recv); const char *typestr = rb_type_str(type); if (typestr && T_OBJECT <= type && type < T_NIL) rb_raise(rb_eNotImpError, - "method `%s' called on hidden %s object" - " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")", - rb_id2name(mid), typestr, (void *)recv, flags, klass); + "method `%"PRIsVALUE"' called on hidden %s object" + " (%p flags=0x%"PRIxVALUE")", + rb_id2str(mid), typestr, (void *)recv, flags); if (typestr) rb_raise(rb_eNotImpError, - "method `%s' called on unexpected %s object" - " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")", - rb_id2name(mid), typestr, (void *)recv, flags, klass); + "method `%"PRIsVALUE"' called on unexpected %s object" + " (%p flags=0x%"PRIxVALUE")", + rb_id2str(mid), typestr, (void *)recv, flags); else rb_raise(rb_eNotImpError, - "method `%s' called on broken T_???" "(0x%02x) object" - " (%p flags=0x%"PRIxVALUE" klass=0x%"PRIxVALUE")", - rb_id2name(mid), type, (void *)recv, flags, klass); + "method `%"PRIsVALUE"' called on broken T_???" "(0x%02x) object" + " (%p flags=0x%"PRIxVALUE")", + rb_id2str(mid), type, (void *)recv, flags); } } return rb_method_entry(klass, mid, defined_class_ptr); |