From 9fe6bddce5e341fef32914f31bb7a31ec566e1f4 Mon Sep 17 00:00:00 2001 From: kimikage Date: Sun, 27 Sep 2026 23:06:12 +0900 Subject: [PATCH] Support for non-concrete types in `promote_rule(::Type{<:FixedPoint}, ::Type{<:FixedPoint})` --- src/FixedPointNumbers.jl | 9 +++++---- test/traits.jl | 12 +++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index fb99dc7e..dad2ff1c 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 @@ -539,15 +540,15 @@ 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 {X1 <: FixedPoint, X2 <: FixedPoint} - (isconcretetype(X1) && isconcretetype(X2)) || return Union{} X1w, X2w = wrapper(X1), wrapper(X2) if X1w !== X2w - # X1w <: X2w && return X2w # for non-concrete types - # X2w <: X1w && return X1w # for non-concrete types + X1w <: X2w && return X2w + X2w <: X1w && return X1w return promote_type(floattype(X1), floattype(X2)) end X = X1w T1, T2 = rawtype(X1), rawtype(X2) + isconcretetype(T1) && isconcretetype(T2) || return X{promote_type(T1, T2)} f1, f2 = nbitsfrac(X1), nbitsfrac(X2) f = max(f1, f2) # ensure we have enough precision Tp = promote_type(T1, T2) diff --git a/test/traits.jl b/test/traits.jl index c248b4c0..63d5646c 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 @@ -18,3 +18,13 @@ struct MyReal <: Real end @test_skip(@test_throws MethodError floattype(MyReal)) # TODO: eliminate `@test_skipped` when depwarn is eliminated. See #177. 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