diff --git a/base/generator.jl b/base/generator.jl index 26bb7c7d91b5d..7b539517e9075 100644 --- a/base/generator.jl +++ b/base/generator.jl @@ -89,6 +89,12 @@ Base.HasShape{1}() julia> Base.IteratorSize((2,3)) Base.HasLength() + +julia> Base.IteratorSize(Iterators.cycle(1:5)) +Base.SizeUnknown() + +julia> Base.IteratorSize(Iterators.cycle(1:0)) +Base.SizeUnknown() ``` """ IteratorSize(x) = IteratorSize(typeof(x)) diff --git a/base/iterators.jl b/base/iterators.jl index 5b061f60573b1..a152de006d832 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -1017,7 +1017,10 @@ cycle(xs, n::Integer) = flatten(repeated(xs, n)) eltype(::Type{Cycle{I}}) where {I} = eltype(I) IteratorEltype(::Type{Cycle{I}}) where {I} = IteratorEltype(I) -IteratorSize(::Type{Cycle{I}}) where {I} = IsInfinite() # XXX: this is false if iterator ever becomes empty +function IteratorSize(::Type{Cycle{I}}) where {I} + IS = IteratorSize(I) + (IS === IsInfinite() || IS == HasShape{0}()) ? IsInfinite() : SizeUnknown() +end iterate(it::Cycle) = iterate(it.xs) isdone(it::Cycle) = isdone(it.xs) diff --git a/test/iterators.jl b/test/iterators.jl index ea4ebc5a56e77..d6ca39164efb3 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -1221,6 +1221,18 @@ end @test isempty(Docs.undocumented_names(Iterators)) end +@testset "cycle IteratorSize (#53169)" begin + @test Base.IteratorSize(Iterators.cycle(1:3)) == Base.SizeUnknown() + @test Base.IteratorSize(Iterators.cycle(1:0)) == Base.SizeUnknown() + @test Base.IteratorSize(Iterators.cycle(7)) == Base.IsInfinite() + @test collect(Iterators.cycle(1:0))::Vector{Int} == Int[] + @test Base.IteratorSize(Iterators.cycle(Iterators.Repeated(6))) == Base.IsInfinite() + + @test Base.IteratorSize(typeof(Iterators.cycle(1:3))) == Base.SizeUnknown() + @test Base.IteratorSize(typeof(Iterators.cycle(1:0))) == Base.SizeUnknown() + @test Base.IteratorSize(typeof(Iterators.cycle(Iterators.Repeated(6)))) == Base.IsInfinite() +end + # Filtered list comprehension (`Filter` construct) type inference @test Base.infer_return_type((Vector{Any},)) do xs [x for x in xs if x isa Int]