From 5505b2a053fb04a763217bc66c1f8b091e8168de Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Wed, 25 Sep 2024 16:58:37 +0200 Subject: [PATCH] fix infinite recursion in `promote_type` for `Irrational` Fixes #51001 --- base/irrationals.jl | 11 ++++++++++- test/numbers.jl | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/base/irrationals.jl b/base/irrationals.jl index eafe388162353..f66994bdaa87b 100644 --- a/base/irrationals.jl +++ b/base/irrationals.jl @@ -45,7 +45,16 @@ promote_rule(::Type{<:AbstractIrrational}, ::Type{Float16}) = Float16 promote_rule(::Type{<:AbstractIrrational}, ::Type{Float32}) = Float32 promote_rule(::Type{<:AbstractIrrational}, ::Type{<:AbstractIrrational}) = Float64 promote_rule(::Type{<:AbstractIrrational}, ::Type{T}) where {T<:Real} = promote_type(Float64, T) -promote_rule(::Type{S}, ::Type{T}) where {S<:AbstractIrrational,T<:Number} = promote_type(promote_type(S, real(T)), T) + +function promote_rule(::Type{S}, ::Type{T}) where {S<:AbstractIrrational,T<:Number} + U = promote_type(S, real(T)) + if S <: U + # prevent infinite recursion + promote_type(Float64, T) + else + promote_type(U, T) + end +end AbstractFloat(x::AbstractIrrational) = Float64(x)::Float64 Float16(x::AbstractIrrational) = Float16(Float32(x)::Float32) diff --git a/test/numbers.jl b/test/numbers.jl index fc3dc2c06bb7c..dc4f2cb613d77 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -2937,6 +2937,14 @@ end @test log(π,ComplexF32(2)) isa ComplexF32 end +@testset "irrational promotion shouldn't recurse without bound, issue #51001" begin + for s ∈ (:π, :ℯ) + T = Irrational{s} + @test promote_type(Complex{T}, T) <: Complex + @test promote_type(T, Complex{T}) <: Complex + end +end + @testset "printing non finite floats" begin let float_types = Set() allsubtypes!(Base, AbstractFloat, float_types)