Skip to content

Commit 664a71d

Browse files
committed
iterator: improve type inference for Filter
This addresses type inference issues with filtered list comprehensions reported in #59111. The root cause is the compiler's inability to perform type refinement in cases like: ```julia let t::Tuple{Any,Any} x, y = t if x isa Int return t # still `::Tuple{Any,Any}` end nothing end ``` Fixing this fundamentally would require extensive improvements to abstract interpretation. As a workaround, I improved the iterators.jl implementation to avoid this pattern. One implementation consideration: if `iterate(f.itr, state...)` always returns `Union{Nothing,Tuple{Any,Any}}`, the `if y isa Tuple{Any,Any}` branch should be unnecessary. However, it's unclear whether we can safely assume this for the iterate interface, so I kept the branch for now.
1 parent 90e3c1a commit 664a71d

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

base/iterators.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,15 @@ filter(flt, itr) = Filter(flt, itr)
534534
function iterate(f::Filter, state...)
535535
y = iterate(f.itr, state...)
536536
while y !== nothing
537-
if f.flt(y[1])
538-
return y
537+
v, s = y
538+
if f.flt(v)
539+
if y isa Tuple{Any,Any}
540+
return (v, s) # incorporate type information that may be improved by user-provided `f.flt`
541+
else
542+
return y
543+
end
539544
end
540-
y = iterate(f.itr, y[2])
545+
y = iterate(f.itr, s)
541546
end
542547
nothing
543548
end

test/iterators.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,3 +1201,8 @@ end
12011201
@testset "Iterators docstrings" begin
12021202
@test isempty(Docs.undocumented_names(Iterators))
12031203
end
1204+
1205+
# Filtered list comprehension (`Filter` construct) type inference
1206+
@test Base.infer_return_type((Vector{Any},)) do xs
1207+
[x for x in xs if x isa Int]
1208+
end == Vector{Int}

0 commit comments

Comments
 (0)