From 38612e03bcbdce12bebf9180faefbfad9d1739c3 Mon Sep 17 00:00:00 2001 From: Klaus Crusius Date: Mon, 8 Oct 2018 21:30:36 +0200 Subject: [PATCH] flatten empty tuple - fix #29112 (#29548) --- base/generator.jl | 1 - base/iterators.jl | 5 ++++- test/iterators.jl | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/base/generator.jl b/base/generator.jl index 73d0e8a2e3ee2..b0f7e32d0b22f 100644 --- a/base/generator.jl +++ b/base/generator.jl @@ -126,4 +126,3 @@ IteratorEltype(::Type) = HasEltype() # HasEltype is the default IteratorEltype(::Type{Generator{I,T}}) where {I,T} = EltypeUnknown() IteratorEltype(::Type{Any}) = EltypeUnknown() -IteratorEltype(::Type{Union{}}) = EltypeUnknown() diff --git a/base/iterators.jl b/base/iterators.jl index ac3c3ad88d9a3..b513d78c89d34 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -873,18 +873,20 @@ julia> collect(Iterators.flatten((1:2, 8:9))) flatten(itr) = Flatten(itr) eltype(::Type{Flatten{I}}) where {I} = eltype(eltype(I)) +eltype(::Type{Flatten{Tuple{}}}) = eltype(Tuple{}) IteratorEltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, IteratorEltype(I)) +IteratorEltype(::Type{Flatten{Tuple{}}}) = IteratorEltype(Tuple{}) _flatteneltype(I, ::HasEltype) = IteratorEltype(eltype(I)) _flatteneltype(I, et) = EltypeUnknown() flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:NTuple{N,Any}}) where {N} = HasLength() flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Tuple}) = SizeUnknown() flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{<:Number}) = HasLength() -flatten_iteratorsize(::Union{HasShape, HasLength}, ::Type{Union{}}) = SizeUnknown() flatten_iteratorsize(a, b) = SizeUnknown() _flatten_iteratorsize(sz, ::EltypeUnknown, I) = SizeUnknown() _flatten_iteratorsize(sz, ::HasEltype, I) = flatten_iteratorsize(sz, eltype(I)) +_flatten_iteratorsize(sz, ::HasEltype, ::Type{Tuple{}}) = HasLength() IteratorSize(::Type{Flatten{I}}) where {I} = _flatten_iteratorsize(IteratorSize(I), IteratorEltype(I), I) @@ -895,6 +897,7 @@ flatten_length(f, ::Type{<:Number}) = length(f.it) flatten_length(f, T) = throw(ArgumentError( "Iterates of the argument to Flatten are not known to have constant length")) length(f::Flatten{I}) where {I} = flatten_length(f, eltype(I)) +length(f::Flatten{Tuple{}}) = 0 @propagate_inbounds function iterate(f::Flatten, state=()) if state !== () diff --git a/test/iterators.jl b/test/iterators.jl index 6e5f88a72cd0d..be5ad0b9398e5 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -370,6 +370,8 @@ end @test_throws ArgumentError length(flatten([[1], [1]])) @test Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1)) == Base.EltypeUnknown() +# see #29112, #29464, #29548 +@test Base.return_types(Base.IteratorEltype, Tuple{Array}) == [Base.HasEltype] # partition(c, n) let v = collect(partition([1,2,3,4,5], 1))