summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-30 06:16:15 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-01-30 06:16:15 +0000
commitbe604acda77b876ac324ef31c492981089894f38 (patch)
tree2514ce987cdc7c1a87f5358f22f59493b45a4b72
parentf1e4777d45f9feea43cd8ca5a65752352bbfa4ec (diff)
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/trunk@44758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--object.c39
-rw-r--r--test/ruby/test_exception.rb16
2 files changed, 39 insertions, 16 deletions
diff --git a/object.c b/object.c
index 8fc85b9..240b4f5 100644
--- a/object.c
+++ b/object.c
@@ -2583,13 +2583,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;
@@ -2597,6 +2600,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)
{
@@ -2605,9 +2618,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;
}
@@ -2622,9 +2633,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;
}
@@ -2639,9 +2648,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 9250038..fc1c209 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -221,6 +221,22 @@ 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
+ assert_raise_with_message(TypeError, /C\u{4032}/) do
+ ""[o]
+ end
+ c.class_eval {def to_int; self; end}
+ assert_raise_with_message(TypeError, /C\u{4032}/) do
+ ""[o]
+ end
+ c.class_eval {def to_a; self; end}
+ assert_raise_with_message(TypeError, /C\u{4032}/) do
+ [*o]
+ end
+ end
+
def test_errat
assert_in_out_err([], "p $@", %w(nil), [])