Skip to content

Commit

Permalink
more precise eltype for some Generator subtypes
Browse files Browse the repository at this point in the history
Fixes #41519

Fixes #48448
  • Loading branch information
nsajko committed Dec 24, 2024
1 parent 8fac39b commit 5707b5e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions base/Base_compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ include("bool.jl")
include("number.jl")
include("int.jl")
include("operators.jl")
include("generator_eltype.jl")
include("pointer.jl")
include("refvalue.jl")
include("cmem.jl")
Expand Down
28 changes: 28 additions & 0 deletions base/generator_eltype.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function eltype(::Type{Generator{A, typeof(identity)}}) where {A}
eltype(A)
end

function IteratorEltype(::Type{Generator{A, typeof(identity)}}) where {A}
IteratorEltype(A)
end

function eltype(::Type{Generator{A, Fix1{typeof(getindex), B}}} where {A}) where {B}
if B <: Type
# a user may overload `getindex(user_type)` to return a non-`Vector` `AbstractVector`
Any
else
eltype(B)
end
end

function IteratorEltype(::Type{Generator{A, Fix1{typeof(getindex), B}}} where {A}) where {B}
if B <: Type
EltypeUnknown()
else
IteratorEltype(B)
end
end

function eltype(::Type{Generator{A, Fix1{typeof(getfield), B}}} where {A}) where {B}
typejoin(fieldtypes(B)...)
end
29 changes: 29 additions & 0 deletions test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,35 @@ end
@test last(Iterators.filter(iseven, (Iterators.map(identity, 1:3)))) == 2
end

@testset "`eltype` for `Generator` involving `Fix` and `getindex`/`getfield` (issue #41519)" begin
@testset "correct `eltype`" begin
f = Base.Fix1(getindex, Int)
i = [3, 7]
r = map(f, i)
t = Iterators.map(f, i)
@test eltype(r) <: @inferred eltype(t)
@test (@inferred Base.IteratorEltype(t)) isa Base.IteratorEltype
end
@testset "precise `eltype`" begin
for (f, i) (
(identity, [3, 7]),
(Base.Fix1(getindex, [3, 7]), 1:2),
(Base.Fix1(getfield, (; a = 3, b = 7)), 1:2),
(Base.Fix1(getfield, (; a = 3, b = 7)), [:a, :b]),
)
r = map(f, i)
t = Iterators.map(f, i)
@test eltype(r) == @inferred eltype(t)
@test (@inferred Base.IteratorEltype(t)) isa Base.IteratorEltype
end
end
end

@testset "issue #48448" begin
it = union(i for i in 1:5)
@test Int == @inferred eltype(it)
end

@testset "isempty and isdone for Generators" begin
itr = eachline(IOBuffer("foo\n"))
gen = (x for x in itr)
Expand Down

0 comments on commit 5707b5e

Please sign in to comment.