summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-15 16:29:10 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-15 16:29:10 +0000
commite68cf6f561560b624ea7a74eda0bd9d58f7020b1 (patch)
treeb180422d43c56733bf0f2c35c677864577f52753
parent257ec8c9afd3cfc6e191a582d42390ce83f53c1e (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.c39
-rw-r--r--test/ruby/test_exception.rb19
-rw-r--r--version.h2
-rw-r--r--vm_eval.c33
4 files changed, 59 insertions, 34 deletions
diff --git a/object.c b/object.c
index 350418e68b..9ded75f9d3 100644
--- a/object.c
+++ b/object.c
@@ -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), [])
diff --git a/version.h b/version.h
index 1a42056c2d..7b40e1078b 100644
--- a/version.h
+++ b/version.h
@@ -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
diff --git a/vm_eval.c b/vm_eval.c
index 88f05ebe4f..7644aff9c1 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -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);