Skip to content

Commit

Permalink
Fix regression in map and collect (JuliaLang#43120)
Browse files Browse the repository at this point in the history
`promote_typejoin_tuple` returned a type which was more precise
than the one which `map` and `collect` actually use via `promote_type`,
triggering an assertion error in corner cases.
  • Loading branch information
nalimilan authored and LilithHafner committed Feb 22, 2022
1 parent 00b2cba commit 89c95de
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 8 deletions.
16 changes: 8 additions & 8 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}
Expand Down
2 changes: 2 additions & 0 deletions test/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions test/generic_map_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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...)
Expand Down

0 comments on commit 89c95de

Please sign in to comment.