[Bug #18937] Coerce non-real non-Numeric into Complex at comparisons

This commit is contained in:
Nobuyoshi Nakada 2022-08-31 11:01:59 +09:00
Родитель a9b59e24f4
Коммит 9212d96307
2 изменённых файлов: 19 добавлений и 7 удалений

Просмотреть файл

@ -1124,15 +1124,23 @@ nucomp_cmp(VALUE self, VALUE other)
if (!k_numeric_p(other)) {
return rb_num_coerce_cmp(self, other, idCmp);
}
if (nucomp_real_p(self)) {
if (RB_TYPE_P(other, T_COMPLEX) && nucomp_real_p(other)) {
if (!nucomp_real_p(self)) {
return Qnil;
}
if (RB_TYPE_P(other, T_COMPLEX)) {
if (nucomp_real_p(other)) {
get_dat2(self, other);
return rb_funcall(adat->real, idCmp, 1, bdat->real);
}
else if (f_real_p(other)) {
get_dat1(self);
}
else {
get_dat1(self);
if (f_real_p(other)) {
return rb_funcall(dat->real, idCmp, 1, other);
}
else {
return rb_num_coerce_cmp(dat->real, other, idCmp);
}
}
return Qnil;
}

Просмотреть файл

@ -568,19 +568,23 @@ class Complex_Test < Test::Unit::TestCase
end
class ObjectX
def +(x) Rational(1) end
def initialize(real = true, n = 1) @n = n; @real = real; end
def +(x) Rational(@n) end
alias - +
alias * +
alias / +
alias quo +
alias ** +
def coerce(x) [x, Complex(1)] end
def coerce(x) [x, Complex(@n)] end
def real?; @real; end
end
def test_coerce2
x = ObjectX.new
y = ObjectX.new(false)
%w(+ - * / quo ** <=>).each do |op|
assert_kind_of(Numeric, Complex(1).__send__(op, x))
assert_kind_of(Numeric, Complex(1).__send__(op, x), op)
assert_kind_of(Numeric, Complex(1).__send__(op, y), op)
end
end