diff --git a/base/promotion.jl b/base/promotion.jl index 469eb0bd8e4a8..13b50366e1d2b 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -84,22 +84,35 @@ function typejoin(@nospecialize(a), @nospecialize(b)) while a.name !== b.name a = supertype(a) end - aprimary = unwrap_unionall(a.name.wrapper) + if a.name === Type.body.name + ap = a.parameters[1] + bp = b.parameters[1] + if ((isa(ap,TypeVar) && ap.lb === Bottom && ap.ub === Any) || + (isa(bp,TypeVar) && bp.lb === Bottom && bp.ub === Any)) + # handle special Type{T} supertype + return Type + end + end + aprimary = a.name.wrapper # join on parameters n = length(a.parameters) if n == 0 return aprimary end - p = Vector{Any}(undef, n) + vars = [] for i = 1:n ai, bi = a.parameters[i], b.parameters[i] if ai === bi || (isa(ai,Type) && isa(bi,Type) && typeseq(ai,bi)) - p[i] = ai + aprimary = aprimary{ai} else - p[i] = aprimary.parameters[i] + pushfirst!(vars, aprimary.var) + aprimary = aprimary.body end end - return rewrap_unionall(a.name.wrapper{p...}, a.name.wrapper) + for v in vars + aprimary = UnionAll(v, aprimary) + end + return aprimary end b = supertype(b) end diff --git a/test/core.jl b/test/core.jl index 844e6abf0f53a..661fd3914f2fc 100644 --- a/test/core.jl +++ b/test/core.jl @@ -127,6 +127,20 @@ end @test typejoin(Tuple{Vararg{Int,2}}, Tuple{Int,Int,Int}) === Tuple{Int,Int,Vararg{Int}} @test typejoin(Tuple{Vararg{Int,2}}, Tuple{Vararg{Int}}) === Tuple{Vararg{Int}} +# issue #26321 +struct T26321{N,S<:NTuple{N}} + t::S +end +let mi = T26321{3,NTuple{3,Int}}((1,2,3)), mf = T26321{3,NTuple{3,Float64}}((1.0,2.0,3.0)) + J = T26321{3,S} where S<:(Tuple{T,T,T} where T) + @test typejoin(typeof(mi),typeof(mf)) == J + a = [mi, mf] + @test a[1] === mi + @test a[2] === mf + @test eltype(a) == J + @test a isa Vector{<:T26321{3}} +end + # promote_typejoin returns a Union only with Nothing/Missing combined with concrete types for T in (Nothing, Missing) @test Base.promote_typejoin(Int, Float64) === Real @@ -6015,4 +6029,4 @@ g25907b(x) = x[1]::Complex @test g25907b(Union{Complex{Int}, Complex{UInt}, Nothing}[1im]) === 1im #issue #26363 -@test eltype(Ref(Float64(1))) === Float64 \ No newline at end of file +@test eltype(Ref(Float64(1))) === Float64