Permalink
Browse files

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
  • Loading branch information...
1 parent f1e4777 commit be604acda77b876ac324ef31c492981089894f38 @nobu nobu committed Jan 30, 2014
Showing with 39 additions and 16 deletions.
  1. +23 −16 object.c
  2. +16 −0 test/ruby/test_exception.rb
View
39 object.c
@@ -2583,20 +2583,33 @@ 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;
}
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;
}
View
16 test/ruby/test_exception.rb
@@ -221,6 +221,22 @@ def test_raise_with_wrong_number_of_arguments
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), [])

0 comments on commit be604ac

Please sign in to comment.