diff --git a/base/promotion.jl b/base/promotion.jl index 21245f0e05c70b..845e16ca499d30 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -168,19 +168,17 @@ function promote_typejoin_union(::Type{T}) where T return Any # TODO: compute more precise bounds elseif T isa Union return promote_typejoin(promote_typejoin_union(T.a), promote_typejoin_union(T.b)) - elseif T <: Tuple - return typejoin_union_tuple(T) - else + elseif T isa DataType + T <: Tuple && return typejoin_union_tuple(T) return T + else + error("unreachable") # not a type?? end end -function typejoin_union_tuple(T::Type) +function typejoin_union_tuple(T::DataType) @_pure_meta u = Base.unwrap_unionall(T) - u isa Union && return typejoin( - typejoin_union_tuple(Base.rewrap_unionall(u.a, T)), - typejoin_union_tuple(Base.rewrap_unionall(u.b, T))) p = (u::DataType).parameters lr = length(p)::Int if lr == 0 @@ -194,8 +192,10 @@ function typejoin_union_tuple(T::Type) ci = Union{} elseif U isa Union ci = typejoin(U.a, U.b) + elseif U isa UnionAll + return Any # TODO: compute more precise bounds else - ci = U + ci = promote_typejoin_union(U) end if i == lr && Core.Compiler.isvarargtype(pi) c[i] = isdefined(pi, :N) ? Vararg{ci, pi.N} : Vararg{ci} diff --git a/test/broadcast.jl b/test/broadcast.jl index 1cad14de44c5f1..b3899ddb063df7 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -1011,6 +1011,8 @@ end @test typeof.([iszero, iszero]) == [typeof(iszero), typeof(iszero)] @test isequal(identity.(Vector{<:Union{Int, Missing}}[[1, 2],[missing, 1]]), [[1, 2],[missing, 1]]) + @test broadcast(i -> ((x=i, y=(i==1 ? 1 : "a")), 3), 1:4) isa + Vector{Tuple{NamedTuple{(:x, :y)}, Int}} end @testset "Issue #28382: eltype inconsistent with getindex" begin diff --git a/test/generic_map_tests.jl b/test/generic_map_tests.jl index abd9a31946a9ad..b155370dd64650 100644 --- a/test/generic_map_tests.jl +++ b/test/generic_map_tests.jl @@ -75,6 +75,8 @@ function generic_map_tests(mapf, inplace_mapf=nothing) @test isequal(map(identity, Vector{<:Union{Int, Missing}}[[1, 2],[missing, 1]]), [[1, 2],[missing, 1]]) @test map(x -> x < 0 ? false : x, Int[]) isa Vector{Integer} + @test map(i -> ((x=i, y=(i==1 ? 1 : "a")), 3), 1:4) isa + Vector{Tuple{NamedTuple{(:x, :y)}, Int}} end function testmap_equivalence(mapf, f, c...)