Skip to content

Commit edea1de

Browse files
authored
Fix regression in map and collect (#43120)
`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.
1 parent 455236e commit edea1de

File tree

3 files changed

+12
-8
lines changed

3 files changed

+12
-8
lines changed

base/promotion.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,19 +168,17 @@ function promote_typejoin_union(::Type{T}) where T
168168
return Any # TODO: compute more precise bounds
169169
elseif T isa Union
170170
return promote_typejoin(promote_typejoin_union(T.a), promote_typejoin_union(T.b))
171-
elseif T <: Tuple
172-
return typejoin_union_tuple(T)
173-
else
171+
elseif T isa DataType
172+
T <: Tuple && return typejoin_union_tuple(T)
174173
return T
174+
else
175+
error("unreachable") # not a type??
175176
end
176177
end
177178

178-
function typejoin_union_tuple(T::Type)
179+
function typejoin_union_tuple(T::DataType)
179180
@_pure_meta
180181
u = Base.unwrap_unionall(T)
181-
u isa Union && return typejoin(
182-
typejoin_union_tuple(Base.rewrap_unionall(u.a, T)),
183-
typejoin_union_tuple(Base.rewrap_unionall(u.b, T)))
184182
p = (u::DataType).parameters
185183
lr = length(p)::Int
186184
if lr == 0
@@ -194,8 +192,10 @@ function typejoin_union_tuple(T::Type)
194192
ci = Union{}
195193
elseif U isa Union
196194
ci = typejoin(U.a, U.b)
195+
elseif U isa UnionAll
196+
return Any # TODO: compute more precise bounds
197197
else
198-
ci = U
198+
ci = promote_typejoin_union(U)
199199
end
200200
if i == lr && Core.Compiler.isvarargtype(pi)
201201
c[i] = isdefined(pi, :N) ? Vararg{ci, pi.N} : Vararg{ci}

test/broadcast.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,8 @@ end
10111011
@test typeof.([iszero, iszero]) == [typeof(iszero), typeof(iszero)]
10121012
@test isequal(identity.(Vector{<:Union{Int, Missing}}[[1, 2],[missing, 1]]),
10131013
[[1, 2],[missing, 1]])
1014+
@test broadcast(i -> ((x=i, y=(i==1 ? 1 : "a")), 3), 1:4) isa
1015+
Vector{Tuple{NamedTuple{(:x, :y)}, Int}}
10141016
end
10151017

10161018
@testset "Issue #28382: eltype inconsistent with getindex" begin

test/generic_map_tests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ function generic_map_tests(mapf, inplace_mapf=nothing)
7575
@test isequal(map(identity, Vector{<:Union{Int, Missing}}[[1, 2],[missing, 1]]),
7676
[[1, 2],[missing, 1]])
7777
@test map(x -> x < 0 ? false : x, Int[]) isa Vector{Integer}
78+
@test map(i -> ((x=i, y=(i==1 ? 1 : "a")), 3), 1:4) isa
79+
Vector{Tuple{NamedTuple{(:x, :y)}, Int}}
7880
end
7981

8082
function testmap_equivalence(mapf, f, c...)

0 commit comments

Comments
 (0)