mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
object.c: fix conversion failure message
* object.c (convert_type_with_id): fix failure message for explicit conversion. rb_convert_type_with_id and rb_check_convert_type_with_id are not only for implicit conversions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59919 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
92e3ffdf78
commit
581be44ede
2 changed files with 27 additions and 18 deletions
44
object.c
44
object.c
|
@ -2885,13 +2885,33 @@ static const struct conv_method_tbl {
|
||||||
};
|
};
|
||||||
#define IMPLICIT_CONVERSIONS 7
|
#define IMPLICIT_CONVERSIONS 7
|
||||||
|
|
||||||
|
static int
|
||||||
|
conv_method_index(const char *method)
|
||||||
|
{
|
||||||
|
static const char prefix[] = "to_";
|
||||||
|
|
||||||
|
if (strncmp(prefix, method, sizeof(prefix)-1) == 0) {
|
||||||
|
const char *const meth = &method[sizeof(prefix)-1];
|
||||||
|
int i;
|
||||||
|
for (i=0; i < numberof(conv_method_names); i++) {
|
||||||
|
if (conv_method_names[i].method[0] == meth[0] &&
|
||||||
|
strcmp(conv_method_names[i].method, meth) == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberof(conv_method_names);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int index)
|
convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int index)
|
||||||
{
|
{
|
||||||
VALUE r = rb_check_funcall(val, method, 0, 0);
|
VALUE r = rb_check_funcall(val, method, 0, 0);
|
||||||
if (r == Qundef) {
|
if (r == Qundef) {
|
||||||
if (raise) {
|
if (raise) {
|
||||||
const char *msg = index < IMPLICIT_CONVERSIONS ?
|
const char *msg =
|
||||||
|
((index < 0 ? conv_method_index(rb_id2name(method)) : index)
|
||||||
|
< IMPLICIT_CONVERSIONS) ?
|
||||||
"no implicit conversion of" : "can't convert";
|
"no implicit conversion of" : "can't convert";
|
||||||
const char *cname = NIL_P(val) ? "nil" :
|
const char *cname = NIL_P(val) ? "nil" :
|
||||||
val == Qtrue ? "true" :
|
val == Qtrue ? "true" :
|
||||||
|
@ -2911,21 +2931,9 @@ convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int ind
|
||||||
static VALUE
|
static VALUE
|
||||||
convert_type(VALUE val, const char *tname, const char *method, int raise)
|
convert_type(VALUE val, const char *tname, const char *method, int raise)
|
||||||
{
|
{
|
||||||
ID m = 0;
|
int i = conv_method_index(method);
|
||||||
int i = numberof(conv_method_names);
|
ID m = i < numberof(conv_method_names) ?
|
||||||
static const char prefix[] = "to_";
|
conv_method_names[i].id : rb_intern(method);
|
||||||
|
|
||||||
if (strncmp(prefix, method, sizeof(prefix)-1) == 0) {
|
|
||||||
const char *const meth = &method[sizeof(prefix)-1];
|
|
||||||
for (i=0; i < numberof(conv_method_names); i++) {
|
|
||||||
if (conv_method_names[i].method[0] == meth[0] &&
|
|
||||||
strcmp(conv_method_names[i].method, meth) == 0) {
|
|
||||||
m = conv_method_names[i].id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!m) m = rb_intern(method);
|
|
||||||
return convert_type_with_id(val, tname, m, raise, i);
|
return convert_type_with_id(val, tname, m, raise, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2973,7 +2981,7 @@ rb_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
|
||||||
VALUE v;
|
VALUE v;
|
||||||
|
|
||||||
if (TYPE(val) == type) return val;
|
if (TYPE(val) == type) return val;
|
||||||
v = convert_type_with_id(val, tname, method, TRUE, 0);
|
v = convert_type_with_id(val, tname, method, TRUE, -1);
|
||||||
if (TYPE(v) != type) {
|
if (TYPE(v) != type) {
|
||||||
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
||||||
}
|
}
|
||||||
|
@ -3017,7 +3025,7 @@ rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
|
||||||
|
|
||||||
/* always convert T_DATA */
|
/* always convert T_DATA */
|
||||||
if (TYPE(val) == type && type != T_DATA) return val;
|
if (TYPE(val) == type && type != T_DATA) return val;
|
||||||
v = convert_type_with_id(val, tname, method, FALSE, 0);
|
v = convert_type_with_id(val, tname, method, FALSE, -1);
|
||||||
if (NIL_P(v)) return Qnil;
|
if (NIL_P(v)) return Qnil;
|
||||||
if (TYPE(v) != type) {
|
if (TYPE(v) != type) {
|
||||||
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
||||||
|
|
|
@ -923,6 +923,7 @@ class TestObject < Test::Unit::TestCase
|
||||||
_issue = "Bug #7539"
|
_issue = "Bug #7539"
|
||||||
assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
|
assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
|
||||||
assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
|
assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
|
||||||
|
assert_raise_with_message(TypeError, "can't convert Array into Rational") {Rational([42])}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_copied_ivar_memory_leak
|
def test_copied_ivar_memory_leak
|
||||||
|
|
Loading…
Reference in a new issue