From 2d314e88335639fe4e25f886fced13c3a5eef890 Mon Sep 17 00:00:00 2001 From: kimikage Date: Sun, 27 Sep 2026 23:06:12 +0900 Subject: [PATCH] Relax the type constraints for `promote_rule(::Type{<:FixedPoint}, ::Type{<:FixedPoint})` --- src/FixedPointNumbers.jl | 21 ++++++++++++++------- test/traits.jl | 12 +++++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index 0e394c0..37193fd 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -49,7 +49,8 @@ reinterpret(::Type{X}, x::T) where {T <: Integer, X <: FixedPoint{T}} = X(x, 0) # static parameters nbitsfrac(::Type{X}) where {T, f, X <: FixedPoint{T,f}} = f -rawtype(::Type{X}) where {T, X <: FixedPoint{T}} = T +rawtype(::Type{X}) where {T <: Integer, X <: FixedPoint{T}} = T +rawtype(::Type{<:FixedPoint}) = Union{} # Don't care the constraints for `T` # traits based on static parameters signbits(::Type{X}) where {T, X <: FixedPoint{T}} = T <: Unsigned ? 0 : 1 @@ -531,12 +532,18 @@ promote_rule(::Type{X}, ::Type{Tr}) where {X <: FixedPoint, Tr <: Rational} = Tr promote_rule(::Type{X}, ::Type{Ti}) where {X <: FixedPoint, Ti <: Integer} = floattype(X) -function promote_rule(::Type{X1}, ::Type{X2}) where {T1, f1, X1 <: FixedPoint{T1,f1}, - T2, f2, X2 <: FixedPoint{T2,f2}} - X = wrapper(X1) - X !== wrapper(X2) && return promote_type(floattype(X1), floattype(X2)) - - f = max(f1, f2) # ensure we have enough precision +function promote_rule(::Type{X1}, ::Type{X2}) where {X1 <: FixedPoint, X2 <: FixedPoint} + X1w, X2w = wrapper.((X1, X2)) + if X1w !== X2w + X1w <: X2w && return X2w + X2w <: X1w && return X1w + return promote_type(floattype(X1), floattype(X2)) + end + X = X1w + T1, T2 = rawtype.((X1, X2)) + isconcretetype(T1) && isconcretetype(T2) || return X{promote_type(T1, T2)} + f1, f2 = nbitsfrac.((X1, X2)) + f = max(f1, f2) # ensure we have enough precision Tp = promote_type(T1, T2) T = (T1 <: Signed || T2 <: Signed) ? signedtype(Tp) : Tp # make sure we have enough integer bits diff --git a/test/traits.jl b/test/traits.jl index 0987051..4dadccd 100644 --- a/test/traits.jl +++ b/test/traits.jl @@ -1,5 +1,5 @@ using FixedPointNumbers, Test -using FixedPointNumbers: bitwidth +using FixedPointNumbers: bitwidth, rawtype struct MyReal <: Real end struct MyInteger <: Integer end @@ -32,3 +32,13 @@ struct MyInteger <: Integer end @test_throws MethodError floattype(MyReal) # See #177. @test floattype(MyInteger) === Float64 end + +@testset "rawtype" begin + @test rawtype(FixedPoint) === Union{} + @test rawtype(Normed) === Union{} + @test rawtype(Fixed) === Union{} + @test rawtype(Normed{<:Unsigned}) === Union{} + @test rawtype(Fixed{Union{Int8, Int16}}) === Union{Int8, Int16} + @test rawtype(N0f8) === UInt8 + @test rawtype(Q0f7) === Int8 +end