Skip to content

Commit

Permalink
Fix Rational{T} constructor for abstract T (#41229)
Browse files Browse the repository at this point in the history
(cherry picked from commit e34c77b)
  • Loading branch information
sostock authored and staticfloat committed Dec 22, 2022
1 parent 85339d2 commit ec3e664
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
7 changes: 4 additions & 3 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@ unsafe_rational(num::T, den::T) where {T<:Integer} = unsafe_rational(T, num, den
unsafe_rational(num::Integer, den::Integer) = unsafe_rational(promote(num, den)...)

@noinline __throw_rational_argerror_typemin(T) = throw(ArgumentError("invalid rational: denominator can't be typemin($T)"))
function checked_den(num::T, den::T) where T<:Integer
function checked_den(::Type{T}, num::T, den::T) where T<:Integer
if signbit(den)
den = -den
signbit(den) && __throw_rational_argerror_typemin(T)
signbit(den) && __throw_rational_argerror_typemin(typeof(den))
num = -num
end
return unsafe_rational(T, num, den)
end
checked_den(num::T, den::T) where T<:Integer = checked_den(T, num, den)
checked_den(num::Integer, den::Integer) = checked_den(promote(num, den)...)

@noinline __throw_rational_argerror_zero(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
function Rational{T}(num::Integer, den::Integer) where T<:Integer
iszero(den) && iszero(num) && __throw_rational_argerror_zero(T)
num, den = divgcd(num, den)
return checked_den(T(num), T(den))
return checked_den(T, T(num), T(den))
end

Rational(n::T, d::T) where {T<:Integer} = Rational{T}(n, d)
Expand Down
4 changes: 4 additions & 0 deletions test/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -607,3 +607,7 @@ end
@testset "checked_den with different integer types" begin
@test Base.checked_den(Int8(4), Int32(8)) == Base.checked_den(Int32(4), Int32(8))
end

@testset "Rational{T} with non-concrete T (issue #41222)" begin
@test @inferred(Rational{Integer}(2,3)) isa Rational{Integer}
end

0 comments on commit ec3e664

Please sign in to comment.