diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 8d46fcffa3ad58..b84c54fb8cb3b4 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -298,7 +298,8 @@ function invmod(n::T) where {T<:BitInteger} end # ^ for any x supporting * -to_power_type(x) = convert(Base._return_type(*, Tuple{typeof(x), typeof(x)}), x) +to_power_type(x::Number) = first(promote(x, one(x), x*x)) +to_power_type(x) = x @noinline throw_domerr_powbysq(::Any, p) = throw(DomainError(p, LazyString( "Cannot raise an integer x to a negative power ", p, ".", "\nConvert input to float."))) diff --git a/test/math.jl b/test/math.jl index c0a2d8bf8c9f8f..6b225e62fcf0cb 100644 --- a/test/math.jl +++ b/test/math.jl @@ -1498,6 +1498,20 @@ end n = Int64(1024 / log2(E)) @test E^n == Inf @test E^float(n) == Inf + + # #55633 + struct Issue55633 <: Number end + struct Issue55633Squared <: Number end + Base.:(*)(::Issue55633, ::Issue55633) = Issue55633Squared() + Base.promote_rule(::Type{Issue55633}, ::Type{Issue55633Squared}) = Int + Base.convert(::Type{Int}, ::Issue55633) = 3 + Base.convert(::Type{Int}, ::Issue55633Squared) = 9 + for x ∈ (im, pi, Issue55633()) + p = promote(one(x), x, x*x) + for y ∈ 0:2 + @test all((t -> ===(t...)), zip(x^y, p[y + 1])) + end + end end # Test that sqrt behaves correctly and doesn't exhibit fp80 double rounding.