Skip to content

Commit 228e0fb

Browse files
committed
Fix a precision issue in abstract_iteration
If the first loop exits in the first iteration, the `statetype` is still `Bottom`. In that case, the new `stateordonet` needs to be determined with the two-arg version of `iterate` again. Fixes #41022.
1 parent e87e30c commit 228e0fb

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,12 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
862862
# the precise (potentially const) state type
863863
statetype = widenconst(statetype)
864864
valtype = widenconst(valtype)
865-
while valtype !== Any
865+
if statetype === Bottom
866+
stateordonet = abstract_call_known(interp, iteratef, nothing, Any[Const(iteratef), itertype], sv).rt
867+
else
866868
stateordonet = abstract_call_known(interp, iteratef, nothing, Any[Const(iteratef), itertype, statetype], sv).rt
869+
end
870+
while valtype !== Any
867871
stateordonet = widenconst(stateordonet)
868872
nounion = typesubtract(stateordonet, Nothing, 0)
869873
if !isa(nounion, DataType) || !(nounion <: Tuple) || isvatuple(nounion) || length(nounion.parameters) != 2
@@ -879,6 +883,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
879883
end
880884
valtype = tmerge(valtype, nounion.parameters[1])
881885
statetype = tmerge(statetype, nounion.parameters[2])
886+
stateordonet = abstract_call_known(interp, iteratef, nothing, Any[Const(iteratef), itertype, statetype], sv).rt
882887
end
883888
push!(ret, Vararg{valtype})
884889
return ret, nothing

test/compiler/inference.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,6 +2875,7 @@ partial_return_2(x) = Val{partial_return_1(x)[2]}
28752875
# Precision of abstract_iteration
28762876
f_splat(x) = (x...,)
28772877
@test Base.return_types(f_splat, (Pair{Int,Int},)) == Any[Tuple{Int, Int}]
2878+
@test Base.return_types(f_splat, (UnitRange{Int},)) == Any[Tuple{Vararg{Int}}]
28782879

28792880
# issue #32699
28802881
f32699(a) = (id = a[1],).id

0 commit comments

Comments
 (0)