diff --git a/src/interface.jl b/src/interface.jl index 33dd132c..c3b3d6f6 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -40,7 +40,23 @@ function promote_operation_fallback( ::Type{S}, ::Type{T}, ) where {S,T} - return typeof(op(_instantiate_zero(S), _instantiate_oneunit(T))) + if isconcretetype(S) && isconcretetype(T) + return typeof(op(_instantiate_zero(S), _instantiate_oneunit(T))) + else + return promote_type(S, T) + end +end + +function promote_operation_fallback( + op::typeof(/), + ::Type{S}, + ::Type{T}, +) where {S<:Integer,T<:Integer} + if isconcretetype(S) && isconcretetype(T) + return typeof(op(_instantiate_zero(S), _instantiate_oneunit(T))) + else + return promote_type(float(S), float(T)) + end end function promote_operation_fallback( @@ -48,14 +64,22 @@ function promote_operation_fallback( ::Type{S}, ::Type{T}, ) where {F<:Function,S,T} - return typeof(op(_instantiate_zero(S), _instantiate_zero(T))) + if isconcretetype(S) && isconcretetype(T) + return typeof(op(_instantiate_zero(S), _instantiate_zero(T))) + else + return promote_type(S, T) + end end function promote_operation_fallback( op::F, args::Vararg{Type,N}, ) where {F<:Function,N} - return typeof(op(_instantiate_zero.(args)...)) + if all(isconcretetype, args) + return typeof(op(_instantiate_zero.(args)...)) + else + return promote_type(args...) + end end promote_operation_fallback(::typeof(*), ::Type{T}) where {T} = T @@ -103,6 +127,13 @@ function promote_operation_fallback( ) end +function promote_operation( + ::Union{typeof(real),typeof(imag)}, + ::Type{Complex{T}}, +) where {T} + return T +end + """ promote_operation(op::Function, ArgsTypes::Type...) diff --git a/test/int.jl b/test/int.jl index ad2538e2..b5693725 100644 --- a/test/int.jl +++ b/test/int.jl @@ -28,6 +28,18 @@ import MutableArithmetics as MA ) @test_throws err MA.promote_operation(op, Int, Vector{Int}) end + for op in [+, -, *, /, div] + @test MA.promote_operation(op, Int, Number) == Number + @test MA.promote_operation(op, Number, Int) == Number + end + @test MA.promote_operation(/, Int, Integer) == Float64 + @test MA.promote_operation(/, Integer, Integer) == Float64 + @test MA.promote_operation(/, Integer, Int) == Float64 + @test MA.promote_operation(gcd, Int, Integer) == Integer + @test MA.promote_operation(gcd, Integer, Integer) == Integer + @test MA.promote_operation(gcd, Integer, Int) == Integer + @test MA.promote_operation(&, Integer, Integer, Integer) == Integer + @test MA.promote_operation(&, Integer, Integer, Int) == Integer end @testset "add_to!! / add!!" begin @test MA.mutability(Int, MA.add_to!!, Int, Int) isa MA.IsNotMutable diff --git a/test/interface.jl b/test/interface.jl index 8c4262a1..e73af0a7 100644 --- a/test/interface.jl +++ b/test/interface.jl @@ -57,6 +57,11 @@ Base.@irrational theodorus 1.73205080756887729353 sqrt(big(3)) MathConstants.catalan @test MA._instantiate(typeof(theodorus)) == theodorus end + + for op in [real, imag] + @test MA.promote_operation(op, ComplexF64) == Float64 + @test MA.promote_operation(op, Complex{Real}) == Real + end end @testset "Errors" begin diff --git a/test/rewrite_generic.jl b/test/rewrite_generic.jl index 5faac7b1..160ec508 100644 --- a/test/rewrite_generic.jl +++ b/test/rewrite_generic.jl @@ -89,8 +89,7 @@ function test_rewrite_nonconcrete_vector() y = Vector{Union{Float64,String}}(x) @test MA.@rewrite(x' * y, move_factors_into_sums = false) == x' * y @test MA.@rewrite(x .+ y, move_factors_into_sums = false) == x .+ y - # Reproducing buggy behavior in MA.@rewrite. - @test_broken MA.@rewrite(x + y, move_factors_into_sums = false) == x + x + @test MA.@rewrite(x + y, move_factors_into_sums = false) == x + x return end diff --git a/test/utilities.jl b/test/utilities.jl index 3433fabd..eb8c5c32 100644 --- a/test/utilities.jl +++ b/test/utilities.jl @@ -7,7 +7,7 @@ include("dummy.jl") # Allocating size for allocating a `BigInt`. Half size on 32-bit. -const BIGINT_ALLOC = @static if VERSION >= v"1.12" +const BIGINT_ALLOC = @static if VERSION >= v"1.12-beta1" Sys.WORD_SIZE == 64 ? 72 : 36 elseif VERSION >= v"1.11" Sys.WORD_SIZE == 64 ? 56 : 28