From 0fa004007e53c26170c58c19861f7f7a3a81f0f8 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Wed, 10 Jan 2018 22:29:59 +0100 Subject: [PATCH] Stop promoting all type parameters Do this only for NamedTuple (and Tuple since typejoin() already handles it). Else types may not implement necessary conversions, which triggers errors. --- base/namedtuple.jl | 3 +++ base/promotion.jl | 25 ++++++++++--------------- test/generic_map_tests.jl | 4 ++-- test/tuple.jl | 4 ++-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/base/namedtuple.jl b/base/namedtuple.jl index 6606456a43462d..45473f44460d9f 100644 --- a/base/namedtuple.jl +++ b/base/namedtuple.jl @@ -55,6 +55,9 @@ indexed_next(t::NamedTuple, i::Int, state) = (getfield(t, i), i+1) isempty(::NamedTuple{()}) = true isempty(::NamedTuple) = false +promote_rule(::ExactPromotion, ::Type{NamedTuple{n, S}}, ::Type{NamedTuple{n, T}}) where {n, S, T} = + NamedTuple{n, promote_type(ExactPromotion(), S, T)} + convert(::Type{NamedTuple{names,T}}, nt::NamedTuple{names,T}) where {names,T} = nt convert(::Type{NamedTuple{names}}, nt::NamedTuple{names}) where {names} = nt diff --git a/base/promotion.jl b/base/promotion.jl index 705ed7d4eafb78..6cc0aade1d0a4f 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -95,8 +95,6 @@ function join_types(@nospecialize(a), @nospecialize(b), f::Function, joinparams: ai, bi = a.parameters[i], b.parameters[i] if ai === bi || (isa(ai,Type) && isa(bi,Type) && typeseq(ai,bi)) p[i] = ai - elseif aprimary <: joinparams && isa(ai,Type) && isa(bi,Type) - p[i] = f(ai, bi) else p[i] = aprimary.parameters[i] end @@ -207,16 +205,14 @@ Union{Float64, Int64} julia> promote_type(ExactPromotion(), Int32, Int64) Int64 -# FIXME: should this be Union{Float32, BigInt}? julia> promote_type(ExactPromotion(), Float32, BigInt) BigFloat julia> promote_type(ExactPromotion(), Int16, Float16) Float16 -# FIXME: should this be Float16? julia> promote_type(ExactPromotion(), Int64, Float16) -Union{Float16, Int64} +Real julia> promote_type(ExactPromotion(), Int8, UInt16) UInt16 @@ -272,10 +268,9 @@ function promote_rule end # Fallback so that rules defined without DefaultPromotion() are used promote_rule(::DefaultPromotion, ::Type{T}, ::Type{S}) where {T,S} = promote_rule(T, S) -# TODO: change ::Type{T} to ::Type{<:Any}? -promote_rule(::DefaultPromotion, ::Type{Any}, ::Type{T}) where {T} = Any +promote_rule(::DefaultPromotion, ::Type{Any}, ::Type{<:Any}) = Any promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom -promote_rule(::Type{Any}, ::Type{T}) where {T} = Any +promote_rule(::Type{Any}, ::Type{<:Any}) = Any promote_rule(::ExactPromotion, ::Type{<:Any}, ::Type{<:Any}) = Bottom promote_rule(::ExactPromotion, ::Type{Any}, ::Type) = Any @@ -382,13 +377,13 @@ promote(p::PromotionStyle, x::T, y::T, zs::T...) where {T} = (x, y, zs...) # this function should only be called when DefaultPromotion falls back to ExactPromotion, # just before the latter falls back to typejoin(). But it should not be called when # ExactPromotion is used directly, as it triggers errors in places where typejoin() would be fine. -#= function promote_result(::ExactPromotion, - ::Type{T},::Type{S}, - ::Type{Bottom},::Type{Bottom}) where {T<:Number,S<:Number} - @_inline_meta - promote_to_supertype(T, S, typejoin(T,S)) -end - =# +# function promote_result(::ExactPromotion, +# ::Type{T},::Type{S}, +# ::Type{Bottom},::Type{Bottom}) where {T<:Number,S<:Number} +# @_inline_meta +# promote_to_supertype(T, S, typejoin(T,S)) +# end +# # promote numeric types T and S to typejoin(T,S) if T<:S or S<:T # for example this makes promote_type(Integer,Real) == Real without # promoting arbitrary pairs of numeric types to Number. diff --git a/test/generic_map_tests.jl b/test/generic_map_tests.jl index 6fcecbe9159763..fb2444134f0727 100644 --- a/test/generic_map_tests.jl +++ b/test/generic_map_tests.jl @@ -31,8 +31,8 @@ function generic_map_tests(mapf, inplace_mapf=nothing) @test mapf(f, Int[], Float64[]) == Union{}[] # map with different result types let m = mapf(x->x+1, Number[1, 2.0]) - @test isa(m, Vector{BigFloat}) - @test m == BigFloat[2, 3.0] + @test isa(m, Vector{Real}) + @test m == Real[2, 3.0] end # AbstractArray map for N-arg case diff --git a/test/tuple.jl b/test/tuple.jl index 578f4899a7df5c..934ec3de57906f 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -184,9 +184,9 @@ end @test eltype(Tuple{Int, Missing}) === Union{Missing, Int} @test eltype(Tuple{Int, Nothing}) === Union{Nothing, Int} @test eltype(Tuple{Int, Missing, Float64}) === Union{Missing, Real} - @test eltype(Tuple{Int, Nothing, Float64}) === Union{Missing, Real} + @test eltype(Tuple{Int, Nothing, Float64}) === Union{Nothing, Real} @test eltype(Tuple{Int, Missing, Int8}) === Union{Missing, Int} - @test eltype(Tuple{Int, Nothing, Int8}) === Union{Missing, Int} + @test eltype(Tuple{Int, Nothing, Int8}) === Union{Nothing, Int} end @testset "mapping" begin