Skip to content

Commit d694548

Browse files
authored
Merge pull request #21108 from JuliaLang/mh/tuple_eltype
RFC: Use `typejoin` of the field types for `eltype` of heterogeneous `Tuple`s
2 parents 56bfb23 + 4752d24 commit d694548

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

base/tuple.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ first(t::Tuple) = t[1]
6363

6464
eltype(::Type{Tuple{}}) = Bottom
6565
eltype(::Type{<:Tuple{Vararg{E}}}) where {E} = E
66+
function eltype(t::Type{<:Tuple})
67+
@_pure_meta
68+
t isa Union && return typejoin(eltype(t.a), eltype(t.b))
69+
= unwrap_unionall(t)
70+
r = Union{}
71+
for ti in.parameters
72+
r = typejoin(r, rewrap_unionall(unwrapva(ti), t))
73+
end
74+
return r
75+
end
6676

6777
# version of tail that doesn't throw on empty tuples (used in array indexing)
6878
safe_tail(t::Tuple) = tail(t)

test/tuple.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,14 @@ end
6565
@test eltype((1,2,3)) === Int
6666
@test eltype((1.0,2.0,3.0)) <: AbstractFloat
6767
@test eltype((true, false)) === Bool
68-
@test eltype((1,2.0, false)) === Any
68+
@test eltype((1, 2.0, false)) === typejoin(Int, Float64, Bool)
6969
@test eltype(()) === Union{}
70+
@test eltype(Tuple{Int, Float64, Vararg{Bool}}) === typejoin(Int, Float64, Bool)
71+
@test eltype(Tuple{Int, T, Vararg{Bool}} where T <: AbstractFloat) ===
72+
typejoin(Int, AbstractFloat, Bool)
73+
@test eltype(Tuple{Int, Bool, Vararg{T}} where T <: AbstractFloat) ===
74+
typejoin(Int, AbstractFloat, Bool)
75+
@test eltype(Union{Tuple{Int, Float64}, Tuple{Vararg{Bool}}}) === typejoin(Int, Float64, Bool)
7076

7177
begin
7278
local foo

0 commit comments

Comments
 (0)