diff --git a/base/tuple.jl b/base/tuple.jl index b3799e57d6fba..3b45f812fc0b6 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -63,6 +63,16 @@ first(t::Tuple) = t[1] eltype(::Type{Tuple{}}) = Bottom eltype(::Type{<:Tuple{Vararg{E}}}) where {E} = E +function eltype(t::Type{<:Tuple}) + @_pure_meta + t isa Union && return typejoin(eltype(t.a), eltype(t.b)) + t´ = unwrap_unionall(t) + r = Union{} + for ti in t´.parameters + r = typejoin(r, rewrap_unionall(unwrapva(ti), t)) + end + return r +end # version of tail that doesn't throw on empty tuples (used in array indexing) safe_tail(t::Tuple) = tail(t) diff --git a/test/tuple.jl b/test/tuple.jl index 20ccbe348587c..70f08a30f667a 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -65,8 +65,14 @@ end @test eltype((1,2,3)) === Int @test eltype((1.0,2.0,3.0)) <: AbstractFloat @test eltype((true, false)) === Bool -@test eltype((1,2.0, false)) === Any +@test eltype((1, 2.0, false)) === typejoin(Int, Float64, Bool) @test eltype(()) === Union{} +@test eltype(Tuple{Int, Float64, Vararg{Bool}}) === typejoin(Int, Float64, Bool) +@test eltype(Tuple{Int, T, Vararg{Bool}} where T <: AbstractFloat) === + typejoin(Int, AbstractFloat, Bool) +@test eltype(Tuple{Int, Bool, Vararg{T}} where T <: AbstractFloat) === + typejoin(Int, AbstractFloat, Bool) +@test eltype(Union{Tuple{Int, Float64}, Tuple{Vararg{Bool}}}) === typejoin(Int, Float64, Bool) begin local foo